数字组合的总和

Sum of combinations of numbers

我想以尽可能快的方式解决数学问题。 我有一组 1 到 n 之间的自然数,例如 {1,2,3,4,n=5} 我想计算这样的公式:

s = 1*2*3*4+1*2*3*5+1*2*4*5+1*3*4*5+2*3*4*5

如您所见,求和中的每个元素都是集合中 n-1 个数字的乘积。例如在(1*2*3*4)中排除了5,在(1*2*3*5)中排除了4。我知道一些乘法是重复的,例如 (1*2) 在 3 个乘法中重复。我怎样才能用最少的乘法来解决这个问题。

抱歉英语不好。 谢谢。

以下是最直接的答案。

def f(n):
    result = 0
    nList = [i+1 for i in range(n)]
    for i in range(len(nList)):
        result += reduce(lambda x, y: x*y,(nList[:i]+nList[i+1:]))
return result

演练 - 使用 reduce 函数将所有长度为 n-1 的列表相乘并添加到变量结果中。

如果只想尽量减少乘法的次数,可以用加法代替所有的乘法,像这样:

// Compute 1*2*…*n
mult_all(n):
    if n = 1
        return 1
    res = 0
    // by adding 1*2*…*(n-1) an entirety of n times
    for i = 1 to n do
        res += mult_all(n-1)
    return res

// Compute sum of 1*2*…*(i-1)*(i+1)*…*n
sum_of_mult_all_but_one(n):
    if n = 1
        return 0
    // by computing 1*2*…*(n-1) + (sum 1*2*…*(i-1)*(i+1)*…*(n-1))*n
    res = mult_all(n-1)
    for i = 1 to n do
        res += sum_of_mult_all_but_one(n-1)
    return res

这是一个适用于 javascript 的答案。这不是最快的方法,因为它没有优化,但如果你只想找到答案,它应该可以工作。

function combo(n){
var mult = 1;
var sum = 0;
for (var i = 1; i <= n; i++){
    mult = 1;
    for (var j = 1; j<= n; j++){
        if(j != i){
            mult = mult*j;
        }
    }
    sum += mult;
}
return (sum);
}

alert(combo(n));

这里有一种不"cheat"的方法,即用重复的加法代替乘法或使用除法。这个想法是用

替换你的表达式

1*2*3*4 + 5*(1*2*3 + 4*(1*2 + 3*(1 + 2)))

这对数字 1 到 5 使用了 9 次乘法。一般来说,我认为乘法次数会比第 (n-1) 个三角数 n * (n - 1) / 2 - 1 少一个。这是 Python 代码,它存储中间阶乘值以将乘法次数减少到 6,或者通常是 2 * n - 4,加法计数相同(但其中一半只是加 1):

def f(n):
    fact = 1
    term = 2
    sum = 3
    for j in range(2, n):
        fact *= j
        term = (j + 1) * sum
        sum = fact + term
    return sum

找到最快算法的唯一方法是用一种语言对所有算法进行编码,并且运行每个算法都使用一个计时器。