斐波那契数列及相关问题
来源:互联网 发布:数据库建模工具有哪些 编辑:程序博客网 时间:2024/06/05 02:19
斐波那契数列是这样一个数列0,1,1,2,3,5,8,13,21......可以很容易的看出斐波那契数列的规律,斐波那契数列的定义如下:
0 n=0
f(n)= 1 n=1
f(n-1)+f(n-2) n>1
问题:实现一个函数,输入n,求斐波那契数列的第n项
解法一:递归
<span style="font-family:SimSun;font-size:14px;">long long Fibonacci(unsigned int n){ if(n <= 0) return 0; if(n == 1) return 1; return Fibonacci(n-1) + Fibonacci(n - 2);}</span>
此算法的效率是很低的,会有大量的重复操作,时间复杂度以n的指数方式增加。
调用次数:c(n)是求第n项调用的次数 c(0)=1;c(1)=1;c(n)=c(n-1)+c(n-2)+1;
解法二:循环
为了避免重复计算,可以把已经得到的数列中间项保存起来,直接使用,从上往下算,首先根据f(0),f(1)计算出f(2),再根据f(1),f(2)计算出f(3)...一次类推就可以计算出第n项了。
<span style="font-family:SimSun;font-size:14px;">long long Fibonacci(unsigned n){ int result[2] = {0 , 1}; if(n < 2) return result[n]; long long fibMinusOne = 1; long long fibMinusTwo = 0; for(unsigned int i = 2 ; i <= n ; ++i) { fibN = fibMinusOne + fibMinusTwo; fibMinusTwo = fibMinusOne; fibMinusOne = fibN; } return fibN;}</span>
相关问题1:一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
思路:首先考虑简单情况,如果只有1级,那么有1种跳法,如果有2级,有两种跳法,一次跳两级,另一种是分两次跳,每次跳一级。
把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数
目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另一种选择是第一次跳2级,此时跳法数目等于后面剩下n-2级台阶的跳法数
目,即为f(n-2)。因此,n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)。可以看出这实际上就是斐波那契数列。解法有以上两种。
相关问题2:一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法?
用f(n)表示青蛙跳上n级台阶的跳法数,青蛙一次性跳上n级台阶的跳法数1(n级跳),设定f(0) = 1;
当n = 1 时, 只有一种跳法,即1级跳:f(1) = 1;
当n = 2 时, 有两种跳的方式,一次跳2级和两次跳每次跳一级:f(2) = f(1) + f(0) = 2;
当n = 3 时,有三种跳的方式,第一次跳出一级后,后面还有f(3-1)中跳法; 第一次跳出二级后,后面还有f(3-2)中跳法;第一次跳出三级后,后面还有f(3-3)中跳法
f(3) = f(2) + f(1)+f(0)=4;
当n = n 时,共有n种跳的方式,第一次跳出一级后,后面还有f(n-1)中跳法; 第一次跳出二级后,后面还有f(n-2)中跳法..........................第一次跳出n级后, 后面有f(n-n)中跳法.
f(n) = f(n-1)+f(n-2)+f(n-3)+..........+f(n-n)=f(0)+f(1)+f(2)+.......+f(n-1)
又因为f(n-1)=f(0)+f(1)+f(2)+.......+f(n-2)
两式相减得:f(n)-f(n-1)=f(n-1)
可以得到递归等式: f(n) = 2*f(n-1) n >= 2
f(n)=2*2*2....*f(0)=2^n-1
相关问题3:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
思想:把长条n*2的覆盖问题分解,第一步,若竖着覆盖一个2*1的方块,那么剩下的为2*(n-1)块,否则,若横着覆盖,应用两块,覆盖一个2*2的块,剩下2*(n-2),这两种覆盖的方式都各有一种,这个问题等同于递归f(n)=f(n-1)+f(n-2)
<span style="font-family:SimSun;font-size:14px;">int main(){ long long n,k,i,j,t; while(scanf("%lld",&n)!=EOF) { i=j=t=1; for(k=0;k<n-1;k++) { t=i+j;j=i;i=t; } printf("%lld\n",t); } return 0;}</span>
- 斐波那契数列及相关问题
- 斐波那契数列及相关问题
- 斐波那契数列的相关问题及算法实现
- 斐波那契数列相关问题总结
- 斐波那契数列及青蛙跳台阶问题
- 斐波那契数列及青蛙跳台阶问题
- 斐波那契数列及青蛙跳台阶问题
- 斐波那契数列及系列问题
- 斐波那契数列相关
- 斐波那契数列的相关
- 斐波那契数列相关
- 斐波那契数列相关
- 斐波那契数列相关
- 斐波那契数列相关
- 斐波那契数列问题
- 斐波那契数列问题
- 斐波那契数列{大数问题}
- 斐波那契数列系列问题
- tcp/ip --------- IP选路
- 九度1104:整除问题
- Java加密系列之(四)对称加密算法
- 超过 130 个你需要了解的 vim 命令
- 黑马程序员——Java基础——多线程
- 斐波那契数列及相关问题
- json使用键值解析方法
- Eclipse中切换SVN账号
- 【AJAX探索之路系列】之一:AJAX开篇
- struts2--中
- 对于Java中多线程互斥锁初步了解
- 关于重定向和转发的理解
- 初始化 赋值 拷贝
- UBUNTU配置mail发送邮件