请考虑以下代码段:
int fib(int N)
{
if(N<2) return 1;
return (fib(N-1) + fib(N-2));
}
鉴于fib
从main调用,N为10,35,67,...(比如说),总呼叫数是多少
是fib
?
这个问题有什么关系吗?
PS:这是一个理论问题,不应该被执行。
编辑:
我知道其他方法可以更快地计算Fibonacci系列。
我想要一个解决方案,计算fib的调用次数为fib(40),fib(50),..没有编译器的帮助,在考试条件下你应该回答类似于这个问题的40个问题规定的时间(约30分钟)。
谢谢,
答案 0 :(得分:11)
让 f(n)为计算fib(n)
的调用次数。
所以, f 至少是 O(fib(n))。实际上, f(n)是 2 * fib(n) - 1 。我们通过归纳表明了这一点:
存在efficient ways来计算任何Fibonacci项。因此, f(n)也是如此。
答案 1 :(得分:4)
这个问题有什么关系吗? ?
第n个斐波纳契数有一个紧密形式的等式:http://en.wikipedia.org/wiki/Fibonacci_number#Closed_form_expression
在您发布的伪代码中,调用次数满足递归关系
x(n) = x(n-1) + x(n-2) +1 # for n>=2
x(1) = 1
x(0) = 1
这与Fibonacci递归关系几乎相同。通过归纳证明可以证明,对于n> = 0,fib(n)对fib的调用次数等于2 * fib(n)-1。
当然,可以通过使用闭合表单表达式或通过添加代码来记忆先前计算的值来加速计算。
答案 2 :(得分:3)
如上所述,您需要解决以下重复方程式: K(N)= K(N-1)+ K(N-2)1
让我们把它写成n-1:K(n-1)= K(n-2)+ K(n-3)+1
现在,从第一个中减去第二个: K(n)-K(n-1)= K(n-1) - K(n-3),
或
K(n) - 2 * K(n-1)+ K(n-3)= 0.
各自的特征方程式为: x ^ 3 - 2 * x ^ 2 + 1 = 0。
它有以下根:1,(1 + sqrt(5))/ 2,(1-sqrt(5))/ 2
因此对于任何真正的A,B,C以下函数 K(n)= A *(1)^ n + B *((1 + sqrt(5))/ 2)^ n + C *((1-sqrt(5))/ 2)^ n
将是您方程式的解决方案。
要找到A,B,C,您需要定义几个初始值K(0),K(1),K(2)并求解方程组。
答案 3 :(得分:2)
phi是常数
position = ceil(log((n - 0.5)*sqrt(5))/log(phi));
n是斐波纳契数... 这个位置会给你哪个斐波纳契数是n
例如给定13,位置将是7 - 0 1 1 2 3 5 8 13
使用此位置只计算相对于给定斐波那契数的位置-1或您想要的任何位置的斐波纳契数。
Previous Fibo Num = floor((pow(phi,position-1)/sqrt(5))+0.5);
floor((pow(phi, position)/sqrt(5))+0.5)
- 是计算Nth fibonacci num的标准公式(注意 - 这不是近似值)
我刚刚反转这个公式来计算位置并使用位置-1来计算之前的斐波纳契数。
答案 4 :(得分:1)
这是使用Recurrence Relations解决的经典问题。
具体而言,斐波那契问题具有以下参数:
f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)
一旦掌握了解决重复的问题,您就可以轻松找到解决方案(这与fib(n)
完全相同)。
答案 5 :(得分:1)
有趣的问题,我不能给你一个公式,但我写了一个Ruby程序来做它,它适用于我在纸上想出的数字,它应该适用于任何。
#!/usr/bin/ruby
#find out how many times fib() would need to be called
def howmany(n)
a = [ ]
a.push n-1
a.push n-2
while a.select{|n| n > 2}.length > 0
a.map! do |n|
n > 2 ? [n-1,n-2] : n
end
a.flatten!
end
a.length
end
>> howmany(10)
=> 55
这很慢..我现在正在弄清楚35,我会在完成时编辑。
编辑:
>> howmany(35)
=> 9227465