TopCoder算法:BrightLamps - n灯

时间:2015-09-06 09:05:41

标签: algorithm

问题是here

我已经阅读了其他解决方案和想法,但我不理解它们。

以下是 mnbvmar 的想法,你能否详细解释一下呢? 你认为这是对的吗?

  

如果您翻转两个连续的K元素子序列(即use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; //... public function registrationAction() { $request = new Request(); $request = $request->createFromGlobals(); $user = new Users(); $user->setEmail($request->request->get('email')); $user->setPassword($request->request->get('password')); $user->setUsername($request->request->get('login')); $em = $this->getEntityManager(); $em->persist($user); $em->flush(); return new JsonResponse(['response' => true]); } (i, i + 1, ..., i + K - 1)),则只有两个灯光会切换((i + 1, ..., i + K)i)。

     

现在必须注意,可以使用以下两个来完成与i + K - 元素翻转有关的每个组合:

     
      
  1. 切换第一个K灯,

  2.   
  3. K切换任意两盏灯。

  4.         

    K个连续灯的每次切换都是这些操作的复合物)。现在它简单得多了。当然,每次操作都可以进行零次或一次操作(多次执行不会有用)。

         

    假设我们没有在最优解决方案中使用第一个操作。然后我们的序列溶解到K远离K的元素序列中,您可以在其中切换两个连续的元素。这很容易解决;如果K - 序列具有偶数个关闭的灯,则可以将它们全部打开;在相反的情况下,显然我们不能全部打开它们,但是可以在序列中仅留下最不值钱的灯。

         

    如果我们使用第一次操作怎么办?然后我们只需切换第一个i灯,然后执行与之前完全相同的步骤。

1 个答案:

答案 0 :(得分:2)

假设我们有10盏灯A-J和k=4。然后我们可以翻转下面的任何X序列:

ABCDEFGHIJ  
XXXX         //flip starting at A, changes A,B,C,D
 XXXX        //flip starting at B, changes B,C,D,E
  XXXX       //...
   XXXX
    XXXX
     XXXX

如果我们执行从灯“S”开始的翻转序列,并且在它之后执行从S右侧灯开始的翻转序列,例如。 D和E,我们可以看到一些灯被翻转两次(即保持不变),只有第一个和最后一个灯被永久改变:

ABCDEFGHIJ  
   XXXX      //this
    XXXX     //and this together

   X   X     //is the same as this alone  

在两个翻转序列之后,只有D和H与之前不同;
E,F,G翻转两次=不变。所以,使用这种模式,
只能更换两个距离为k的灯(本例中为4个),
而不是k灯 。

现在,在A上使用这种模式也会改变E,并且在E上使用它会改变I.在A,E之外的任何其他灯上使用它,我不会影响A,E,I。 ...换句话说,可以将所有(10)个灯分成k(4)组:

A,E,I  
B,F,J  
C,G  
D,H  

完全独立,即。独立计算每个组的最佳解决方案将为我们提供最佳解决方案(只要我们记得使用上面的开关模式)。

在一组中,让我们采取AEI,我们可以想到相同的模式,规模较小,即。影响E和E影响I(如上所述),可能的翻转模式是

ABCDE
xx
 xx
  xx
   xx  

也许你现在看到,通过链接这些模式,我们可以翻转这组中的任何两个灯,即使它们不是连续的,只要它是两个灯。 IE浏览器。 AB或AC或AD或AE或BC等 现在,获取真实数据,如果关闭灯的数量是偶数,你可以打开如上所述的对,直到所有灯都没有,然后该组完成。如果数字不均匀,请选择值最低的灯作为唯一保持关闭的灯。