让A 成为输入数组。我假设它是按升序排序的。
A = [2,3,6,8,11]
让M[i] 成为到目前为止找到的子列表的数量,总和等于i。
仅以M[0] = 1 开头,因为有一个列表的总和为零,即空列表。
M = [1,0,0,...]
然后从列表A 中一一取出每一项。
在考虑时更新您必须组成每个总和列表的方法的数量
你刚才拿的东西可以用。
Suppose a is the new item
for each j:
if M[j] != 0:
M_next[j+a] = M[j+a] + M[j]
当您发现在此期间达到 10 的任何 M[j] 时,您应该停止算法。
另外,修改以记住列表中的项目,以便能够在最后获得实际列表!
注意事项:
- 您可以使用 sparse 表示
M
- 这类似于那些背包和子集和问题。
也许你会发现很多更好的算法阅读这些。
以下是 Python 中的工作代码:
A = [2,3,6,8,11]
t = sum(A)
M = [0]*(t+1)
M[0] = 1
print 'init M :',M
for a in A:
for j in range(len(M)-1,-1,-1):
if M[j] != 0:
M[j+a] += M[j]
print 'use',a,':',M
及其输出:
init M : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 2 : [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 3 : [1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 6 : [1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 8 : [1, 0, 1, 1, 0, 1, 1, 0, 2, 1, 1, 2, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 11 : [1, 0, 1, 1, 0, 1, 1, 0, 2, 1, 1, 3, 0, 2, 2, 0, 2, 2, 0, 3, 1, 1, 2, 0, 1, 1, 0, 1, 1, 0, 1]
以末尾M[11] = 3的解释为例;
这意味着有 3 个总和等于 11 的子列表。
如果你跟踪进度,你可以看到子列表是{2,3,6},{3,8},{11}。
考虑到您允许 10 个子列表具有 相似 总和。不只是完全相同的金额。您可能希望将终止条件从“如果有任何 M[j] >= 10 则终止”更改为“如果 sum(M[j:j+3]) >= 10 则终止”或类似的内容。