2.斐波那契数列

OpenJudge - 1755:菲波那契数列


解题思路:

(1)斐波那契数列又称兔子数列,第一二项为1,从第三项开始,都等于前两项之和,如果要求第n项,那么必须知道第n-1项和第n-2项,一次类推,发现要求目标值,总要求比它规模更小的子问题,而且最小的子问题我们是知道的,即第一项是1,第二项也是1,满足递归的三要素,所以尝试用递归的写法

(2)设f(n)函数求斐波那契数列的第n项,那么关系表达式为f(n)=f(n-1)+f(n-2),出口条件为if(n==1||n==2)return 1;


#include<bits/stdc++.h>
using namespace std;

int f(int x)
{
	if(x==1||x==2)//递归出口 
	return 1;
	else
	return f(x-1)+f(x-2);//层层递进 
}

int main()
{
	int n;
	cin>>n;
	
	cout<<f(n);
	return 0;
}


优化思路:

(1)当求第5项的时候,发现要求第3项和第4项,要求第3项的时候求了第1项和第2项,要求第4项的时候,求第3项和第2项,发现第3项重复了,造成了子问题重叠,当n比较大的时候,会有很多子问题重叠,造成运行效率低下

(2)该如何优化呢?求过的其实我们可以存到数组中,不用再求,每次函数递进的时候,先判断是否为出口,然后判断该子问题是否被求过,如果被求过,直接返回结果即可,否则的话,继续递归,这样,就免去了很多不必要的重复计算,也叫做记忆化搜索!

(3)设int d 【maxn】数组用来存储求解过的子问题,因为数组初始化都为0,那么只需判断该项也就是d【n】是否为0,如果是,则继续调用,如果不是,说明已被求解过,直接返回d【n】即可


#include<bits/stdc++.h>
using namespace std;
int d[100];
int f(int x)
{
	if(x==1||x==2)//递归出口 
	return 1;
	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
	if(d[x]==0)//如果该子问题没有被求解过 
	d[x]=f(x-1)+f(x-2);//继续递归 
	
	return d[x];//最后返回d[x] 
	
}
int main()
{
	int n;
	cin>>n;
	
	cout<<f(n);
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值