我想以最快的方式解决数学问题。 我有一组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。我知道一些乘法被重复,例如(3 * 2)在3次乘法中重复。如何用最少的乘法来解决这个问题。
抱歉英语不好。 感谢。
答案 0 :(得分:1)
这是一种不会欺骗"通过重复添加或使用除法替换乘法。我们的想法是用
替换你的表达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
找到哪种算法最快的唯一方法是用一种语言编写所有算法,然后使用计时器运行每种算法。
答案 1 :(得分:0)
以下是最简单的答案。
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的列表相乘并添加到变量结果中。
答案 2 :(得分:0)
如果您只想最小化乘法次数,可以用加法替换所有乘法,如下所示:
// 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
答案 3 :(得分:0)
这是一个适用于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));