找到具有相等和的两个子集时出错

时间:2012-06-10 07:25:04

标签: algorithm set dynamic-programming data-partitioning

我一直在尝试将数组划分为两个非空的不相交子集,使得它们的总和相等。

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的学习阶段。而且我觉得有点困难。有人可以帮我找出当前算法中的错误。

1 个答案:

答案 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的集合,因为它总是更大......现在需要使用从较大集合到较小集合的递归。