17:菲波那契数列
总时间限制:1000ms 内存限制:65536kB
描述
菲波那契数列是指这样的数列: 数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。
给出一个正整数k,要求菲波那契数列中第k个数是多少。
输入
输入一行,包含一个正整数k。(1 <= k <= 46)
输出
输出一行,包含一个正整数,表示菲波那契数列中第k个数的大小
样例输入
19
样例输出
4181
求菲波那契数列有限项-递推解法
代码如下:
#include<iostream>
using namespace std;
int main()
{
int k;
cin >> k;
int a1=1,a2=1,sum;
if(k==1 || k==2)
cout << 1;
else
{
for(int i=3; i<=k; ++i)
{
sum=a1+a2;
a1=a2;
a2=sum;
}
cout << sum;
}
return 0;
}
//17:菲波那契数列
//递推求菲波那契数列有限项
求菲波那契数列有限项-递归解法
代码如下:
#include<iostream>
using namespace std;
int Fib(int n)
{
if(n==1 || n==2)
return 1;
else
return Fib(n-1)+Fib(n-2);
}
int main()
{
int k;
cin >> k;
cout << Fib(k);
return 0;
}
//17:菲波那契数列
//递归求菲波那契数列有限项
//递归还需优化否则效率低容易超时,应该用递归记忆化搜索改进
在这里我强调一下,递归虽然代码简单,容易理解,但是通常效率低下,比如上述的这个递归代码在oj上提交后结果就说超时了,如下图所示。
为什么递归效率并不高呢?这是因为递归的调用过程中包含很多重复的计算,如下图所示。
所以我们要把递归解法进行优化,比如这道题我们可以用数组来保存已经在递归过程中求出的值。
求菲波那契数列有限项-递归解法优化
代码如下:
#include<iostream>
using namespace std;
#define num 101
int a[num]; //记录当前数字是否已经求出解
int Fib(int n)
{
if(n==1 || n==2)
return 1;
else if(a[n]!=0)//若求出解则直接返回不用再递归
return a[n];
return a[n]=Fib(n-1)+Fib(n-2);//若还未求出解则继续递归
}
int main()
{
int k;
cin >> k;
cout << Fib(k);
return 0;
}
//17:菲波那契数列
//递归用数组记忆化搜索来求菲波那契数列有限项
最后我想说栈在递归中的应用十分重要。可以将递归算法转换为非递归算法,通常需要借助栈来实现这种转换,但是消除递归也不一定需要使用栈,比如用迭代的方式来消除递归。
感谢观看!巫师三天下第一!