这是一个比编程/实现更多的算法/证明问题,所以如果StackOverflow不适合它就道歉。
至于问题:
假设我们有一组数字,每个数字必须是正整数且幂2
。例如,我们可能有{1, 1, 2, 4, 8, 8, 8, 8, 128}
。我们希望将该集合划分为A
和B
,其中每个元素必须完全位于A
或B
,以便A
'的总和s元素等于B
元素的总和。是否有针对这种情况的多项式时间算法,它总是
A
和B
,使其总和相等? 如果没有多项式时间算法,当然,我很想知道证明这一点的方向(即通过显示与另一个NP难问题的等价)。
我知道有一些问题可能会有所帮助,对于上下文,我会在这里总结一下:
sum(A) = sum(B)
。非常感谢任何帮助。谢谢!
答案 0 :(得分:3)
一种看待这种情况的方法是说你试图表达一个目标数,即总数/ 2,作为所提供数字的总和。这实际上只是改变的问题。
这是一个有用的引理:如果你有一组硬币,其值都是两个值<= 2 ^ k的两个幂,那么你可以准确地做出2 ^ k,或者你不能使任何数字变大,或更大,超过2 ^ k。要看到这一点,拿走你所有的硬币,如果你有一枚以上相同价值的硬币,就把这两枚硬币粘在一起制作一个下一个最高值的硬币,直到硬币耗尽或达到2 ^ k。如果你达到2 ^ k就完成了。如果你用完了,你就拥有了各种价值的单个硬币的集合,它们仍然是2的幂,都小于2 ^ k,每个不同的值只有一个,所以结果不能超过2 ^ k -1
现在要更改目标值,将您的数字视为硬币,并反复将可用的最大硬币放在一边,该硬币不超过您目前所拥有的值与目标值之间的差异。
如果达到目标值,问题就解决了。如果没有,你错过了正确的答案吗?你开始使用最大值的硬币。寻找你的第一个错误 - 你拿了一个2 ^ k大小的硬币,并且有一些方法来弥补不包括这个2 ^ k大小的硬币的余额。但这种神奇的方式是使用不超过2 ^ k的值的硬币来弥补超过2 ^ k的变化。所以在这个正确的答案中,有一组硬币加起来恰好是2 ^ k。拿这个正确的答案,删除加起来2 ^ k的硬币,然后用你使用的2 ^ k的硬币替换它,你得到另一个正确的答案 - 所以你是对的,如果你能得到任何解决方案,你可以通过重复使用可用的最大硬币(数量)小于目标值的距离来获得它。
完整性检查 - 查看http://cs.mcgill.ca/~lyepre/pdf/assignment2-solutions/subsetSumNPCompleteness.pdf中给出的子集和的减少,并注意它需要的数字不是2的精确幂,所以我在这里提出的,证明只有当数字是2的幂,并不声称在多项式时间内解决NP完全问题。