总和组合清单

时间:2012-10-31 02:15:21

标签: algorithm

我需要一个针对此问题的算法:

给定一组n个自然数x1,x2,...,xn,数字S和k。形成从集合中挑选的k个数字的总和(一个数字可以多次选择)和总和S.

换句话说:列出带边界的S的每个可能组合:n <= 256,x <= 1000,k <= 32

E.g。

  problem instance: {1,2,5,9,11,12,14,15}, S=30, k=3
  There are 4 possible combinations
  S=1+14+15, 2+14+14, 5+11+15, 9+9+12.   

有了这些界限,使用蛮力是不可行的,但我认为动态编程是一种很好的方法。

该方案是:表t,其中t [m,v] =由m个数字组成的和v的组合的数量。

1. Initialize t[1,x(i)], for every i.   
2. Then use formula t[m,v]=Sum(t[m-1,v-x(i)], every i satisfied v-x(i)>0), 2<=m<=k.   
3. After obtaining t[k,S], I can trace back to find all the combinations.  

困境是t [m,v]可以通过重复的可交换组合来增加,例如,由于16 = 15 + 1和1 + 15,t [2,16] = 2。此外,最终结果f [3,30]很大,因为1 + 14 + 15,1 + 15 + 14,...,2 + 14 + 14,14 + 2 + 14,......

如何摆脱对称排列?提前谢谢。

1 个答案:

答案 0 :(得分:2)

你可以通过对选择x元素的方式强加一个排序来摆脱排列。使您的表格成为t[m, v, n] =来自v的{​​{1}}个数组成的总和m的三个x1..xn =组合数。现在观察t[m, v, n] = t[m, v, n-1] + t[m-1, v-x_n, n]。这通过仅从它们在x中的外观以相反的顺序生成加数来解决置换问题。因此,例如它将生成15 + 14 + 1和14 + 14 + 2但从未生成14 + 15 + 1。

(你可能不需要填写整个表格,所以你应该懒得计算;事实上,一个memoized递归函数可能就是你想要的。)