递推递归定义

递推与递归对比说明:

  1. 递推(迭代)
  • 特点:自底向上,显式使用循环
  • 优势:效率高(无函数调用开销)
  1. 递归
  • 特点:自顶向下,函数自我调用
  • 优势:代码简洁,直观反映数学定义
  • 缺陷:存在重复计算
  1. 应用选择
  • 优先用递推:存在明显状态转移方程(DP问题)
  • 适合用递归:问题可自然分解为子问题(树形结构)

递推递归例图

左边的例子是用递推做阶乘
执行操作 5 × 4 × 3 × 2 × 1 5×4×3×2×1 5×4×3×2×1

右边的例子是用递归做阶乘
执行操作 1 × 2 × 3 × 4 × 5 1×2×3×4×5 1×2×3×4×5
递推例图

模板代码(阶乘版)

#include <iostream>
using namespace std;
#define int long long
int n;//从1~n的阶乘
int ditui(int x){
	if(x==1)return x;//完成条件,终止递推
	return x*ditui(x-1);
}
int digui(int x){
	if(x==n)return x;//完成条件,终止递归
	return x*digui(x+1);
}
signed main(){
	cin>>n;
	cout <<ditui(n)<<endl;//从顶部开始往下
	cout <<digui(1)<<endl;//从底部开始往上
	return 0;
}

看这模板很简单

分析下时间复杂度(看在什么时候使用合适)避免超时 T L E ( T i m e TLE(Time TLE(Time L i m i t Limit Limit E x c e e d e d ) Exceeded) Exceeded)

方案 时间复杂度 空间复杂度 适用场景
普通递推 O(n) O(1) 线性结构问题
普通递归 O(2ⁿ) O(n) 教学演示
记忆化递归 O(n) O(n) 树形结构问题
尾递归 O(n) O(1) 支持尾调用优化的语言

总结:递推是更高效的,但是递归更方便理解

例题实战

题目传送门 题目传送门 题目传送门

P1255 数楼梯

题目描述

楼梯有 N N N 阶,上楼可以一步上一阶,也可以一步上二阶。

编一个程序,计算共有多少种不同的走法。

输入格式

一个数字,楼梯数。

输出格式

输出走的方式总数。

输入输出样例 #1

输入 #1

4

输出 #1

5

说明/提示

  • 对于 60 % 60\% 60% 的数据, N ≤ 50 N \leq 50 N50
  • 对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 5000 1 \le N \leq 5000 1N5000

分析

题目给出的算法标签除了递推递归
还有之前讲过的高精!!
仔细看数据范围,5000的 n n n看起来不大
实际上算上去会直接爆炸,long long都装不下
这时候就要高精了(其实是交了一次然后炸了/bushi)
点→高精度运算文章传送
继续讲,题面很简单就是给你阶梯,让你选择怎么走
2种选择

  1. 走一步
  2. 走两步

可以先列举几个找找规律
看能不能直接列递推式
n = 1 n=1 n=1时, a n s = 1 ans=1 ans=1
n = 2 n=2 n=2时, a n s = 2 ans=2 ans=2
n = 3 n=3 n=3时, a n s = 3 ans=3 ans=3
n = 4 n=4 n=4时, a n s = 5 ans=5 ans=5
n = 5 n=5 n=5时, a n s = 8 ans=8 ans=8

聪明的你可能已经发现了
这是一个斐波那契数列!
也就是说
只需结合高精算法就可以轻松攻破 A C AC AC的大门
话不多说上代码

例题代码

#include <iostream>
#include <string>
using namespace std;
string sum[10005];//注意这里需要用string定义
int a[100001],b[100001],c[100001];
string add(string a_,string b_){
	int len_a=a_.size();
	int len_b=b_.size();
	for(int i=0;i<len_a;i++){
		a[i]=a_[len_a-1-i]-'0';
	}
	for(int i=0;i<len_b;i++){
		b[i]=b_[len_b-1-i]-'0';
	}
	int len_c=max(len_a,len_b),t=0;
	for(int i=0;i<len_c;i++){
		c[i]=a[i]+b[i]+t;
		if(c[i]>=10){
			t=1;
			c[i]%=10;
		}else{
			t=0;
		}
	}
	if(t){
		len_c++;
		c[len_c-1]=1;
	}
	string s;
	for(int i=len_c-1;i>=0;i--){
		s+=c[i]+'0';
	}
	return s;
}//高精算法,详细介绍可以看我之前的文章,链接在上面
int main(){
	int x;
	cin>>x;//台阶数
	sum[1]="1",sum[2]="2";//初始化
	for(int i=3;i<=x;i++){
		sum[i]=add(sum[i-1],sum[i-2]);
		//斐波那契
	}
	cout <<sum[x];//输出总和
	return 0;
}

题单推荐

递推递归题单 递推递归题单 递推递归题单
题单和例题均来自 洛谷 洛谷 洛谷

~ 完结撒花 完结撒花 完结撒花 ~

附:高精度运算文章传送
没弄懂高精或者想要了解高精度运算的可以看看这篇文章↑
推荐 洛谷 洛谷 洛谷作为你的刷题区域
下一篇预告:结构体或者贪心(把前面的补完)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐