我想计算这样的数字序列:
n*(n-1)+n*(n-1)*(n-2)+n*(n-1)*(n-2)*(n-3)+n*(n-1)*(n-2)*(n-3)*(n-4)+...+n(n-1)...(n-n)
例如n=5
和sum等于320
。
我有一个函数,它计算一个元素:
int fac(int n, int s)
{
if (n > s)
return n*fac(n - 1, s);
return 1;
}
答案 0 :(得分:2)
重新计算每个summand的阶乘是非常浪费的。相反,我建议使用memoization。如果你重新订购
n*(n-1) + n*(n-1)*(n-2) + n*(n-1)*(n-2)*(n-3) + n*(n-1)*(n-2)*(n-3)*...*1
你得到了
n*(n-1)*(n-2)*(n-3)*...*1 + n*(n-1)*(n-2)*(n-3) + n*(n-1)*(n-2) + n*(n-1)
注意如何从1..n的产品开始,然后添加1..n除以1的乘积,然后将产品加1 * 2等。
我认为函数的定义更有效(在Python中):
def f(n):
p = product(range(1, n+1))
sum_ = p
for i in range(1, n-1):
p /= i
sum_ += p
return sum_
此定义的递归版本为:
def f(n):
def go(sum_, i):
if i >= n-1:
return sum_
return sum_ + go(sum_ / i, i+1)
return go(product(range(1, n+1)), 1)
最后但并非最不重要的是,您还可以使用reduce
生成加数列表来定义函数而不进行任何显式递归(这是一个更“实用”的函数 - 如函数式编程一样):
def f(n):
summands, _ = reduce(lambda (lst, p), i: (lst + [p], p / i),
range(1, n),
([], product(range(1, n+1))))
return sum(summands)
这种风格在Haskell等函数式编程语言中非常简洁; Haskell有一个函数调用scanl
,它简化了生成求和,以便定义只是:
f n = sum $ scanl (/) (product [1..n]) [1..(n-2)]
答案 1 :(得分:1)
这样的东西?
function fac(int n, int s)
{
if (n >= s)
return n * fac(n - 1, s);
return 1;
}
int sum = 0;
int s = 4;
n = 5;
while(s > 0)
{
sum += fac(n, s);
s--;
}
print sum; //320
无环版:
int fac(int n, int s)
{
if (n >= s)
return n * fac(n - 1, s);
return 1;
}
int compute(int n, int s, int sum = 0)
{
if(s > 0)
return compute(n, s - 1, sum + fac(n, s));
return sum;
}
print compute(5, 4); //320
答案 2 :(得分:0)
好的不是写的。如果你想解决这个recursiv,我会建议2个方法。 (recrusiv教员的Becaus复杂性是一团糟,运行时间会大幅增加!)
int func(int n){
return func(n, 2);
}
int func(int n, int i){
if (i < n){
return n*(fac(n-1,n-i)+func(n, i + 1));
}else return 0;
}
int fac(int i,int a){
if(i>a){
return i*fac(i-1, a);
}else return 1;
}