2D位数的最大OR值

时间:2017-07-22 14:54:07

标签: algorithm multidimensional-array bit-manipulation dynamic-programming

假设有一个2D数组(m x n)位。

例如:

1 0 0 1 0
1 0 1 0 0 
1 0 1 1 0
0 0 0 0 1

此处m = 4n = 5

我可以翻转(0变为11变为0)任意行中的位。当您翻转特定行中的位时,将翻转 all 位。

我的目标是在给定的一对行之间获得最大OR值。

也就是说,如果给定的行对是(r1, r2),那么我可以在r1r2之间翻转任意数量的行,我应该找到最大可能{{1} ORr1之间所有行的值。

在上面的示例中(考虑具有从1开始的索引的数组),如果r2 = 1且r1 = 4,我可以翻转第1行以获得r2。现在,如果我找到从1到4的所有行的0 1 1 0 1值,我会将值OR作为最大可能的31值(可以有其他解决方案)。

此外,计算OR(r1, r1)(r1, r1+1),...,(r1, r1+2)的答案,同时为{{1 }}

约束

(r1, r2-1)

(r1,r2)

简单的蛮力解决方案的时间复杂度为1 <= m x n <= 10^6。 有更快的计算方法吗?

2 个答案:

答案 0 :(得分:0)

A <= A | B开始,数字A的值只会随着OR个数字增加到A而增加。

因此,我们可以使用二分搜索。

我们可以使用函数来获取两行之间的最大值,并将OR ed结果保存为第三行。然后比较这些第三行中的两行以获得更高级别的行,然后比较其中两个更高级别的行,依此类推,直到只留下一行。

使用您的示例:

array1 = 1 0 0 1 0 [0]
         1 0 1 0 0 [1]
         1 0 1 1 0 [2]
         0 0 0 0 1 [3]

array2 = 1 1 0 1 1 <-- [0] | ~[1]
         1 1 1 1 0 <-- [2] | ~[3]

array3 = 1 1 1 1 1 <-- [0] | [1]

显然,当m不是2的幂时,你可以根据需要截断分支。

所以这将是O(m)时间。请记住,对于大量行,可能没有唯一的解决方案。结果很可能是2 ^ n - 1

重要优化:如果m >= n,则输出必须为2 ^ n - 1。假设我们有两个数字A和B.如果B有k个数字缺失位,那么A~A将保证至少填充其中一个位。通过类似的标记,如果m >= log n,那么输出也必须是2 ^ n - 1,因为每个A~A都可以保证填充{{1}中至少一半的未填充位1}}。

使用这些快捷方式,您可以根据需要进行强力搜索。我不是100%二进制搜索算法适用于每一种情况。

答案 1 :(得分:0)

考虑到在整个矩阵中翻转行然后将它们放在一起以获得尽可能多的1的问题,我声称当列数小于2 ^ m时这是易处理的,其中m是行数。逐行考虑行。在阶段i从0开始计数,你需要填充少于2 ^(m-i)个零。因为翻转行将0变为1,反之亦然,当前行或翻转行将填充这些零中的至少一半。当您完成所有行后,您将填充少于1个零,因此保证此过程可以提供完美的答案。

我声称当列数至少为2 ^ m时,这是易处理的,其中m是行数。有两个可能的翻转行模式,但这只是O(N),其中N是列数。因此,在这种情况下,尝试所有可能的翻转行模式会为您提供O(N ^ 2)算法。