通过补充位掩码来确定最大和数组的算法

时间:2014-12-23 22:59:37

标签: arrays algorithm

我的同事提出的这个问题使我感到困惑。我甚至无法想出一个干净的暴力解决方案。说明问题:

给定一个包含非负整数n的大小为k = [10, 40, 1, 200, 5000, ..., n]的数组,大小为n的位掩码,即mask = 1001....b_n where |mask| = n.和一个表示连续位的整数补充S = 3,找到一个产生最大和数组的掩码配置。

补码大小S用于从位掩码中选择S个连续位,并用其补码替换它。

例如,如果mask = 100001 S = 2可以

  • 通过在MSB
  • 应用掩码,将mask更改为010001
  • 您可以在mask中的任何位迭代地继续补充,直到找到最大大小的数组。

以下是我的观点:

  1. 找到所有2^n位掩码配置,然后应用它们以查找最大和数组
  2. 给定初始掩码配置,查看是否存在步骤1中找到的最大和数组配置的路径。
  3. 再次,我的是指数解决方案。任何有效的人都会受到赞赏。

2 个答案:

答案 0 :(得分:1)

从一个微不足道的观察开始,你永远不会在你的原始面具的同一段上不止一次地应用你的给定位面G,它只包含S 1 s ,M - 这是因为按位xor是可交换的和关联的,允许你按自己的意愿重新排序,而xor'ing一个位掩码给你所有0 s。

给定长度为B的位掩码Sind中的整数索引[0,n),让BestSum(ind, B)成为可获得的最佳总和在[ind:n)时,在输入数组k的{​​{1}}切片上,其中M'[ind, ind + S) = B是执行所有操作后掩码的最终状态。让我们写M',其中B = b.B'是MSB,并考虑b的两种可能性:

  1. b:在这种情况下,您不会在b = M[ind]因此G申请M[ind]
  2. BestSum(ind, B) = b*k[ind] + max(BestSum(ind + 1, B'.0), BestSum(ind + 1, B'.1)):在这种情况下,您将在b != M[ind]申请G,因此M[ind]
  3. 这与边界条件一起为您提供具有运行时BestSum(ind, B) = b*k[ind] + max(BestSum(ind + 1, (~B').0), BestSum(ind + 1, (~B').1))的DP。最佳解决方案是最大值O(n*2^S)

    请注意,我们已经在“边界条件”的基础上解决了所有可达性问题。现在让我们解决这个问题 - 如果对于给定的BestSum(0, B)ind,没有最终配置BM',则定义M'[ind, ind + S) = B。这将确保您需要回答不可达性的唯一情况确实是边界 - 即BestSum(ind, B) = -inf。在ind = n - S(n-S, B)可以访问(n-S, M[n-S:n))的唯一值,从而轻松处理边界。

答案 1 :(得分:0)

以下是否有效?

使用DFS扩展具有所有可能性的树(在每个深度中执行一次翻转),递归的结束条件为:

  1. 达到所有面具的状态为1
  2. 继续回到相同的位置,意味着我们永远不会达到所有面具都是1的状态。(我不确定我们究竟能够检测到这一点。)