【C++算法】递推(斐波那契、上台阶问题)代码详解

一本通 1188:菲波那契数列(2)

题目链接:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)

  • 斐波那契数列问题我们经常用递归解决,但是本题由于数据范围比较大,所以递归层数会非常多,会遇到爆栈的问题,必定会TLE
int fib(int n) {
    if(n==1 || n==2) return 1;
    return fib(n-1)+fib(n-2);
}
  • 因此我们选择用递推解决,同时还有一个问题,题目要求的是菲波那契数列中第 a a a个数对 1000 1000 1000取模得到的结果,我们只需要在计算 F i b o n a c c i Fibonacci Fibonacci数列的时候一边计算一边对 1000 1000 1000取模就可以了,这并不会最终结果
  • 如果我们不一边计算一边取模,而是对单独我们要的那个值进行取模会遇到什么结果?在计算数列的时候就已经爆 i n t int int l o n g   l o n g long\ long long long了,那么在累加求解的过程中就会溢出,最终得到的是负数
#include<bits/stdc++.h>
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

// 解题思路: 想想能不能用递归做呢?不能,因为数据范围很大,递归会爆栈,一定会TLE
//int fib(int n) {
//	if(n==1 || n==2) 
//		return 1;
//	else 
//		return (fib(n-1)+fib(n-2))%1000;
//}

const int N=1e6+5;
int fib[N];
int n;

int main() {
	cin>>n;
	int temp;
	// 预处理计算出所有的fib,再处理查询
	// 初始化:
	fib[1]=fib[2]=1;
	for(int i=3;i<=N;i++) {
		fib[i]=(fib[i-1]+fib[i-2])%1000;
	}
	while(n--) {
//		scanf("%d",&temp);
//		cout<<fib(temp)%1000<<endl;
		// 用递推做法
		scanf("%d",&temp);
		cout<<fib[temp]<<endl;
	}
	return 0;
}

一本通 1189:Pell数列

题目链接:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)

  • 当作业咯

一本通 1190:上台阶

题目链接:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)

  • 其实这道题是动态规划中线性 D P DP DP中非常经典的题目,非常适合新手初步接触动态规划类型题目,从动态规划的四要素来分析该问题
  1. 状态表示, d p [ i ] dp[i] dp[i]:到达第 i i i步台阶的方案数
  2. 初始化, d p [ 1 ] = 1 dp[1]=1 dp[1]=1,到达台阶一的方案只有一种,那就是直接走一步, d p [ 2 ] = 2 dp[2]=2 dp[2]=2,到达台阶二的方案有两种,那就是走两个一步,或者直接走两步, d p [ 3 ] = 4 dp[3]=4 dp[3]=4,到达台阶三的方案有四种,要么走四个一步,要么走两个两步,要么先走两步,再走两个一步,要么先走两个一步,再走一个两步
  3. 状态转移, d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] + d p [ i − 3 ] ( n > = 3 ) dp[i]=dp[i-1]+dp[i-2]+dp[i-3](n>=3) dp[i]=dp[i1]+dp[i2]+dp[i3](n>=3):到达第台阶 i i i要么是从第 i − 1 i-1 i1步台阶走一步上来的,要么是从第 i − 2 i-2 i2步台阶走两步上来的,要么是从第 i − 3 i-3 i3步台阶走三步上来的
  4. 目标值,要求到达第 n n n步台阶方案数,所以直接输出 d p [ n ] dp[n] dp[n]即可
  • 注意就算最大台阶只有 70 70 70步,但数据增长速度很快,所以需要开 l o n g   l o n g long \ long long long才能通过
#include<bits/stdc++.h>
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

// 解题思路: 

const int N=70+5; // 最大台阶数
ll dp[N];
int n;

int main() {
	// 初始化
	dp[1]=1;
	dp[2]=2;
	dp[3]=4;
	// 预处理所有方案
	for(int i=4;i<=N;i++) {
		dp[i]=dp[i-1]+dp[i-2]+dp[i-3];
	}
	while(cin>>n && n!=0) {
		cout<<dp[n]<<endl;
	}
	return 0;
}
  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值