algorithm - 总和组合表

标签 algorithm

我需要一个算法来解决这个问题:

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

换句话说:列出 S 和 Bounds 的所有可能组合:n<=256, x<=1000, k<=32

例如

  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,...

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

最佳答案

您可以通过在选择 x 元素的方式上强加顺序来摆脱排列。使您的表成为三元组 t[m, v, n] = x1 中的 m 数字组成的总和 v 的组合数..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。

(您可能不需要填写整个表格,因此您可能应该延迟计算;事实上,您在这里可能需要一个内存的递归函数。)

关于algorithm - 总和组合表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13150340/

相关文章:

algorithm - 嵌套循环运行时间?

algorithm - 梯度下降不会返回线性函数的错误预测

algorithm - 检测一个整数是否可以写成给定整数的倍数

algorithm - Infomap社区检测理解

algorithm - 如何将请求分派(dispatch)和自动分配给最近的司机

PHP 5.5 password_* 函数重新散列

c++ - 如何以对数时间访问 C++ std::set 中的第 k 个元素?

python - 比大量 IF 语句更好的选择?数值表

algorithm - 为什么以下获取最低硬币找零不起作用

javascript - 我查找数组最大元素的算法的缺陷在哪里?