我一直在尝试将数组划分为两个非空的不相交子集,使得它们的总和相等。
eg. A = {1,2,3,6,88,55,29}
one possible answer = 1+2+3 and 6
我已阅读有关平衡分区问题的mit教程,但我的约束不同。我不必考虑整个集A(意味着它不必是A1 U A2会导致A)。另一个问题是N的限制。每个最多有100个不同的元素(< = 100) 我还阅读了与我的问题相关的THIS帖子,但我无法获得任何内容。
My present Algo --
p[1][a[0]] = 1
for i = 2 to n
for j = 0 to n*n
if( p[i][j] >= 2) stop
p[i][j] += j - a[i] > 0 ? ( p[i-1][j] + p[i-1][j-a[i]] ):0
p[i][j] += j == a[i] ? 1:0
p[i][j] += j < a[i] ? p[i-1][j]:0
解释:
Search for sum j at position i. If we got count at position j >=2 means
there are more than two possibilities for summing up to j.
HERE is sample working code by me
我知道这种方法无法处理不相交的集合,但我无法弄清楚任何其他方法。
我正处于Dynamic Prog的学习阶段。而且我觉得有点困难。有人可以帮我找出当前算法中的错误。
答案 0 :(得分:1)
您的代码似乎没有遍历所有子集。一组大小n
的{{3}}具有2^n-1
非空元素,因此我认为这是算法复杂性的下限。您需要找到一种枚举子集的适当方法,与Power Set
通常,通过逐个添加元素来生成子集。如果使用动态编程,这允许您在一次添加中计算单个集合的总和。实际上,如果您有{1,2,3,6}
并将值保存到12
,则只需添加88
即可找到{1,2,3,6,88}
的总和。
您可以在基本DP之外找到进一步的优化。例如,如果你测试
{88} > {1,2,3,6,29}
首先,您不需要使用{1,2,3,6,29}
测试{88}
(较小的总和)的任何子集。同时你不需要测试任何包含{1,2,3,6,29}
的88的集合,因为它总是更大......现在需要使用从较大集合到较小集合的递归。