Algorithm TopCoder算法:BrightLamps--n Lamps

Algorithm TopCoder算法:BrightLamps--n Lamps,algorithm,Algorithm,问题是 我读过其他人的解决方案和想法,但我不理解他们 以下是mnbvmar的想法,你能详细解释一下吗 你认为这是对的吗 如果翻转两个连续的K元素子序列(即,(i), 我 + 1. ..., 我 + K - 1) 和(i) + 1. ..., 我 + K) ),只有两个灯切换(i和i + K) 现在需要注意的是,可以使用K元素翻转进行的每种组合,也可以使用以下两种方式进行: 切换第一个K灯 按K切换任意两个灯的距离 (连续灯的每次切换都是这些操作的组合)。现在简单多了。当然,每个操作可以执行零

问题是

我读过其他人的解决方案和想法,但我不理解他们

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

如果翻转两个连续的K元素子序列(即,
(i), 我 + 1. ..., 我 + K - 1) 
(i) + 1. ..., 我 + K) 
),只有两个灯切换(
i
i + K

现在需要注意的是,可以使用
K
元素翻转进行的每种组合,也可以使用以下两种方式进行:

  • 切换第一个
    K

  • K
    切换任意两个灯的距离

  • (连续灯的每次切换都是这些操作的组合)。现在简单多了。当然,每个操作可以执行零次或一次(多次执行是没有用的)

    假设我们在最优解中没有使用第一个运算。然后,我们的序列分解为相距
    K
    的元素序列,您可以在其中切换两个连续的元素。这很容易解决;如果
    i
    -th序列有偶数个关闭的灯,则可以将它们全部打开;在相反的情况下,很明显我们不能把它们都打开,但可以只关闭序列中最不值钱的灯

    如果我们使用第一个操作呢?然后我们只需先切换
    K
    灯,然后执行与之前完全相同的步骤


    假设我们有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为例,我们可以用更小的尺度来思考相同的模式,即a影响E和E影响I(如上所述),可能的翻转模式是

    ABCDE
    xx
     xx
      xx
       xx  
    
    也许你现在看到,通过链接这些图案,我们可以翻转这个组中的任意两个灯,即使它们不是连续的,只要是两个灯。例如AB或AC或AD或AE或BC等

    现在,获取真实数据,如果关闭的灯的数量为偶数,您可以如上所述打开对,直到所有灯都取消,然后该组完成。如果数字不均匀,则选择值最低的灯作为唯一保持关闭的灯。

    这里您不了解的是什么?但是,“选择值最低的灯作为唯一保持关闭的灯”有一个问题。当init
    string=“001000001”
    a[]={1000,3,10,8,999,7,4,6,998,10}
    时失败。
    AEI
    “000”
    ,值是
    {1000999998}
    ,因为数字是3,这是奇数,所以我们应该丢弃最低的
    998
    ,但对于其他人来说它非常大。显然,在这种情况下,我们不能放弃最低的一个。@loverszhaokai,这意味着你刚刚发现“mnbvmar”的解决方案不是最优的:)(实际上,我之前并不这么认为:p)是的。我不知道为什么“mnbvmar”的解决方案可以得到正确的答案。例如,
    init string=“00001”
    ,和
    a[]={1,1,1,2}
    K=4
    ,在“mnbvmar”的解决方案中,第一组是“01”,值是
    {1,2}
    ,我们应该丢弃最低的一个,即
    1
    ,但显然我们不能丢弃它,最好的方法是切换前4位,而这一切都将是“11111”。