斐波那契数列
斐波那契数列问题
描述:斐波那契数列(Fibonacci sequence),指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
斐波那契数列以如下被以递推的方法定义:
F(0)=0
F(1)=1
F(n)=F(n-1)+F(n-2)(n ≥ 2,n ∈ N*)
递归算法
#include <iostream>
using namespace std;
int f(int n)
{
if(n==0) return 0;
if(n==1) return 1;
return f(n-1)+f(n-2);
}
int main()
{
cout<<f(5)<<endl;
return 0;
}
非递归算法
1.使用数组储存前一项
#include <iostream>
using namespace std;
int main()
{
int num[100];
num[0]=0;
num[1]=1;
int n=5;
for(int i=2;i<=n;i++){
num[i]=num[i-1]+num[i-2];//数组储存
}
cout<<num[n]<<endl;
return 0;
}
2.使用队列
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int n=5;//要求的第n项
queue <int> Q;//创建队列
Q.push(0);
Q.push(1);
for(int i=2;i<=n;i++){
int a=Q.front();Q.pop();
int b=Q.front();//Q.pop();
Q.push(a+b);
}
Q.pop();//结束之后队列里还剩下两个元素,要出队一个,剩下的才是所求
cout<<Q.front()<<endl;
return 0;
}
迭代算法
a = a + b;
b = a - b ;
完成一次迭代
#include <iostream>
using namespace std;
int fib(int n) {
if (n == 0 || n == 1)
return n;
int a = 1, b = 0;
for (int i = 1; i < n; i++) {
a = a + b;
b = a - b;
}
return a;
}
int main()
{
cout<<fib(5)<<endl;
return 0;
}
效率分析
递归算法在一般情况下会超时,不太适用于网站提交,将其转换为非递归算法
问题展开
爬楼梯问题
小明爬楼梯,他一次可以爬1阶楼梯或者2阶楼梯。
爬1阶楼梯,共有1种方法;
爬2阶楼梯,共有2种方法;
爬3阶楼梯,共有3种方法;
爬4阶楼梯,共有5种方法…
如果爬n阶楼梯,共有多少种方法?
思路
如果要爬到n阶,这个人必须先爬到n-1阶或者n-2阶。如果爬到n-1阶,那么只需要一次爬1阶就可以到达n阶;如果爬到n-2阶,那么只需要一次爬2阶就可以到达n阶。
所以,爬到n阶的方法=爬到n-1阶的方法+爬到n-2阶的方法。
所以这是一个斐波那契数列,F(n)=F(n-1)+F(n-2)。
兔子繁殖问题
有1只兔子,从出生后第3个月起每个月都生1只兔子,小兔子长到第3个月后每个月又生1只兔子,假如兔子都不死,问每个月的兔子总数为多少?
第1个月,有1只兔子;第2个月,有1只兔子;第3个月,有2只兔子;第4个月,有3只兔子;第5个月,有5只兔子…
思路
要求第n个月的兔子,首先第n-1个月的兔子在第n个月全部活着,即有F(n-2)只兔子。而对于第n-2个月的兔子,一部分是最新出生的兔子(第n个月就是他们的第3个月),一部分是老兔子。所以第n-2个月的所有兔子都在第n个月生1只兔子,即有F(n-2)只兔子。最终可以得到F(n)=F(n-1)+F(n-2)。
代码
#include <iostream>
using namespace std;
int main()
{
int n;
int f[100];
f[0]=f[1]=1;
cin>>n;
for(int i=2;i<=n;i++)
{
f[i]=f[i-2]+f[i-1];
}
cout<<f[n]<<endl;
return 0;
}