长度为 N 的可重复组合的总和是多少?

问题描述

长度为 N 的可重复组合的总和是多少?

像 [1,3,5,10],N = 4。

还有

[1,1,1] -> sum is 4

[1,3] -> sum is 6

...

[10,10,10] -> sum is 40

我执行回溯算法。由 python3

res = set()
n = 4
def backtrack(k,path):
    if len(path) == n:
        res.add(sum(path))
        return
    backtrack(k+1,path+[1])
    backtrack(k+1,path+[3])
    backtrack(k+1,path+[5])
    backtrack(k+1,path+[10])
    return
backtrack(0,list())

有没有更有效的解决方案?

解决方法

如果 n elements 顺序不重要,那么你的代码是错误的 例如 [1,1,2,2] ~ [1,2]

您可以创建一个新列表并将原始列表的每个元素重复 n 次。那么问题是how many ways we can select n item from new list,它可以很容易地计算出来 如果您想要所有 sums 的结果集,我认为没有比在所有情况下迭代更好的方法了。

,

O(n*len(list)*numberofdistinctsums) 方法。

我们有两组包含奇数步和偶数步的当前可能和。 我们根据前一步的总和(使用 i+1 个被加数)计算由 i 个被加数形成的新和。

例如,在两轮之后,我们有两个被加数的所有可能和。从前一个集合中获取和 8,我们将三个被加数 8+1,8+3,8+5,8+10 的和放入新集合中,依此类推。

a = [1,3,5,10]
n = 4
sums = [set(a),set()]
for i in range(1,n):
    sums[i%2].clear
    for j in sums[(i+1)%2]:
        for x in a:
            sums[i%2].add(j + x)

print(len(sums[(n-1)%2]))