递归?递推?

news2025/5/18 0:17:24

前言:递归、递推是两种非常常见基础的算法了,但我之前忘了从这基础的先讲起了,大家应该也都略有了解吧!今天突然想写点相关延伸内容,所以还是完整介绍一些吧

递归

递归是一种通过函数调用自身解决问题的算法。在递归算法中,问题被分解为多个更小的子问题,这些子问题与原问题相似,但规模更小,分解的过程一直持续到到达一个基本情况,基本情况是一个可以直接解决而不需要进一步递归的简单问题。

常见的,求最大公约数就用到了递归的思想,代码如下:

#include<iostream>
using namespace std;
int gcd(int a,int b){
	if(a%b==0) return b;
	return gcd(b,a%b);
}
int main(){
	int a,b;
	cin>>a>>b;
	cout<<gcd(a,b);
	return 0;
} 

汉诺塔问题也是非常经典的递归问题,如果你没听说过的话(“那你就out了”*bushi),网上搜一下就有,还有可视化小网站呢,输出移动过程的代码如下:

#include<iostream>
using namespace std;
void move(char x,char y){
	cout<<x<<"->"<<y<<endl;
}
void Hanoi(int n,char a,char b,char c){
	if(n==1){
		move(a,c);
	}
	else{
		Hanoi(n-1,a,c,b);      //将n-1个盘子从A经过C移到B(从上往下都是从小到大排放)
		move(a,c);
		Hanoi(n-1,b,a,c);
	}
}
int main(){
	int n;
	cin>>n;         //A柱上的圆盘数
	Hanoi(n,'A','B','C');   //将n个盘子从A经过B移到C
	return 0;
} 

噢,对了,深度优先搜索( DFS)也是使用递归来实现的

再来道题目感觉一下吧,忘了在哪做到过的,简单说下题目大意。

题目大意:第一行n,表示数组长度,第二行输入n个非负整数,第三行输入目标值t。通过对数组中的每个数字前添加'+'或'-',构造表达式,使结果恰好等于目标值target,问共有几种组合 

思路:排列组合问题,用dfs,处理n个数,每个数都可能正可能负,符合条件计数

#include<iostream>
using namespace std;
int a[20];
int n,t,count;
void dfs(int index,int sum){
	if(index==n+1){
		if(sum==t){
			count++;
		}
		return;
	}
	dfs(index+1,sum+a[index]);
	dfs(index+1,sum-a[index]);
}
int main(){
	cin>>n;
	for(int i=0;i<=n;i++) cin>>a[i];
	cin>>t;
	dfs(1,0);
	cout<<count;
	return 0;
} 

题目:素数环 Prime Ring Problem  洛谷UVA524

思路: 用dfs,从第二个数开始填环(第一个数为1),每填一个数判断于前面数的和是否是素数并标记访问过了,最后一个数还要判断和第一个数的和是否为素数(都很简单啊,好像有点过于简单了,emm要不大白直接往后看吧)

代码:

#include<iostream>
using namespace std;
int n,t=0;
int a[20]={0,1},flag[20]={0,1};
bool ss(int x){
	if(x==1) return 0;
	for(int i=2;i*i<=x;i++){
		if(x%i==0){
			return 0;
		}
	}
	return 1;
}
void print(){
	cout<<"Case t:"<<endl;
	for(int i=1;i<=n;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
void dfs(int index){
	if(index==n+1){
		if(ss(a[index-1]+a[1])){
			print();
		}
		return;
	}
	for(int i=1;i<=n;i++){
		if(!flag[i]&&(ss(i+a[index-1]))){
			a[index]=i;
			flag[i]=1;
			dfs(index+1);
			flag[i]=0;
		}
	}
}
int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=2;i<=n;i++) flag[i]=0;
		t++;
		dfs(2);
		cout<<endl;
	}
	return 0;
} 

还有个常见应用就是二叉树遍历了,这个在分享树的时候再一起分享吧!

递推

递推是一种通过将复杂问题分解为更简单的子问题,从子问题开始求解并将解存储起来以避免重复计算的方法。动态规划就是通过递推关系来高效地解决问题的

最基础的递推问题应该走楼梯了,代码如下:

#include<iostream>
using namespace std;
int a[51]={0,1,2};
int main(){
	int n;    
	cin>>n;
	for(int i=3;i<=n;i++){
		a[i]=a[i-1]+a[i-2];     //从前一阶楼梯到i/从前两阶到i
	}
	cout<<a[n];
	return 0;
} 

要运用递推算法,非常关键的就是找到递推关系式,下面来几题感受一下,就只分析递推关系式,代码就不写了,我觉得有些题若是没遇到过还是比较难想的。以下几道题目来自B站的教学博主钉耙编程-刘春英老师的个人空间-钉耙编程-刘春英老师个人主页-哔哩哔哩视频

题目大意:1月份有一对小兔,一个月后小兔长成大兔,大兔每个月都能生一对小兔(2月1对,3月2对),问第n月有几对小兔,如5月有5对 

思路:f[1]=1,f[2]=1,这个月的兔子数=上个月的兔子数+上个月的大兔数(上上个月的兔子数),所以就是斐波那契数列啦,代码我就不再写了

题目大意:一个平面上有一个圆和n条直线,每一条直线与其他直线相交,且没有3条直线交于一点,试问这些直线会将圆分成多少区域?这其实是个数学问题——n条直线最多能将一个圆分为几个部分(要想把圆分成的块数最多,那么增加的每一条线都不能过前面所有的交点)

思路:第n条直线会于其他n-1条直线相交,被分成n段,增加n个区域,所以f[n]=f[n-1]+n,其实也就是等差数列求和,结果为1+(n*(n+1))/2

题目大意:学生们站成一排,规定女生不能单独站(要么没有,要么不止一个女孩并排站),如n=4,有7种:FFFF,FFFM,MFFF,FFMM,MFFM,MMFF,MMMM 。问n个学生,有几种合法的队列数

思路:若第n个学生为男生,f[n]=f[n-1],只要前n-1个合法就好了;若第n个学生为女生,则第n-1个学生肯定为女生,f[n]=f[n-2]+f[n-4],前n-2个学生合法或者不合法(n-2是女生,n-3是男生)。所以结果为两种情况和f[n]=f[n-1]+f[n-2]+f[n-4]

题目大意:一行有n个方格,用红粉绿三色涂每个格子,要求任何相邻的方格不能同色,且首尾方格也不同色,求有几种涂法

思路:若前n-1个合法,则第n个方格只有一种选择;若前n-1个方格不合法(首尾同色,前n-2个合法),则第n个方格有2种选择。所以f[n]=f[n-1]+2*f[n-2]

大家应该都知道斐波那契数列吧,就是形如f[n]=f[n-1]+f[n-2]的数列,现在介绍几种也是学习算法应该知道的数列

卡特兰数

题目:栈  洛谷P1044

思路:记入栈操作为+1,出栈操作为-1,那么合法操作序列,每个数的前缀和都应该>=0(有入栈才能出栈)。合法序列数=序列总数-不合法序列数。

主要就是一个将求不合法序列数转为求翻转后的序列数有点难以理解。将通项公式化简,也就为(2n)!/((n+1)!*n!),可以直接代。

Cn=C从0到n-1 * C从n-1到0,还好记吧。关键是要知道题目考的是卡特兰数,这样可以帮我们简便解题。也可以计算多个不同的 n,通过观察可得,这道题的答案符合卡特兰数的规律:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012(从第0项开始),这样不用分析直接套卡特兰数的模板就行。 

代码: 

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int f[20]={1};
	for(int i=1;i<=n;i++){
		for(int j=0;j<i;j++){
			f[i]+=f[j]*f[i-j-1];
		}
	}
	cout<<f[n];
	return 0;
} 

题目:矩阵 II  洛谷P1772

思路: 这不就是上面那道题换一个说法吗?继续套模板,但注意,n=100,卡特兰数的增长是很快的,每求一项就模100

代码:

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	long long f[101]={1};
	for(int i=1;i<=n;i++){
		for(int j=0;j<i;j++){
			f[i]+=f[j]*f[i-j-1];
			f[i]%=100;      
		}
	}
	cout<<f[n];
	return 0;
} 

下面这些问题的说法也都满足卡特兰数:

1.候选人A,B,n个人参加投票,投票过程中A从未落后过B(A,B最终票数相等),求投票过程的种数
2.走n*n的方格,从左上角走到右下角,只能在下三角区域(不能越过主对角线),求路程种数
3.求n个节点的二叉树的形态数

第二类斯特林数

题目:三只小猪  P3904

思路:若小猪数<房子数||房子数为0,方案数为0;若小猪数==房子数,方案数为1;若小猪数>房子数,第n只小猪可能自己一间房,或者放入任意一间已有小猪的房子,f[n][m]=f[n-1][m-1]+f[n-1][m]*n

代码:

#include<iostream>
using namespace std;
long long dp[51][51];    //dp[i][j]表示i只小猪j间房子的方案数 
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++){
			if(i==j){
				dp[i][j]=1;
			}else{
				dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*j;
			}
		}
	}
	cout<<dp[n][m];
	return 0;
} 

如果你知道第二类斯特林数(数据递增也是很快的,要用long long/向这种求方案数的题目最好都直接long long,防止爆int),那么又可以直接套模板秒了。

第二类Stirling数表示把n个不同的元素划分为m个非空集合的方案数,写作S ( n , m ) 。

S(n,m)=S(n−1,m−1)+S(n−1,m)∗m   

将n-1个元素放入m-1个集合,第n个元素放入m集合 + n-1个元素放入m个集合,第n个元素放入m个集合的任意一个

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯--结束

冲刺题单 基础 一、简单模拟&#xff08;循环数组日期进制&#xff09; &#xff08;一&#xff09;日期模拟 知识点 1.把月份写为数组&#xff0c;二月默认为28天。 2.写一个判断闰年的方法&#xff0c;然后循环年份的时候判断并更新二月的天数 3.对于星期数的计算&#…

【ChCore Lab 01】Bomb Lab 拆炸弹实验(ARM汇编逆向工程)

文章目录 1. 前言2. 实验代码版本问题3. 关于使用问题4. 宏观分析5. read_line 函数介绍6. phase_0 函数6.1. read_int 函数6.2. 回到 phase_0 函数继续分析6.3. 验证结果 7. phase_1 函数7.2. 验证结果 8. phase_2 函数8.1. read_8_numbers 函数8.2. 回到 phase_2 函数继续分析…

二分答案----

二分答案 - 题目详情 - HydroOJ 问题描述 给定一个由n个数构成的序列a&#xff0c;你可以进行k次操作&#xff0c;每次操作可以选择一个数字&#xff0c;将其1&#xff0c;问k次操作以后&#xff0c;希望序列里面的最小值最大。问这个值是多少。 输入格式 第一行输入两个正…

Transformer多卡训练初始化分布式环境:(backend=‘nccl‘)

Transformer多卡训练初始化分布式环境:(backend=‘nccl’) dist.init_process_group(backend=nccl)在多卡环境下初始化分布式训练环境,并为每个进程分配对应的 GPU 设备。下面为你逐行解释代码的含义: 1. 初始化分布式进程组 try:dist.init_process_group(backend=nccl) e…

Kubernetes集群环境搭建与初始化

1.Kubernetes简介&#xff1a; Kubernetes是Google开源的一个容器编排引擎&#xff0c;它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时&#xff0c;通常要部署该应用的多个实例以便对应用请求进行负载均衡。 在Kubernetes中&#xff0c;我…

Jetson AGX Xavier开发套件使用方法

Jetson AGX Xavier是一款由NVIDIA推出的一款强大的嵌入式AI开发平台&#xff0c;适合边缘计算和目标检测任务。如果你手上有一台 Jetson AGX Xavier Developer Kit&#xff0c;就可以使用它进行明火烟雾目标检测实验。以此为例&#xff0c;为了使你能够从零开始设置设备并完成实…

数据可视化 —— 多边图应用(大全)

一、介绍&#xff1a; 多边形图&#xff0c;也就是在数据可视化中使用多边形来呈现数据的图表&#xff0c;在多个领域都有广泛的应用场景&#xff0c;以下为你详细介绍&#xff1a; 金融领域 投资组合分析&#xff1a;在投资组合管理中&#xff0c;多边形图可用于展示不同资…

小张的工厂进化史——工厂模式

小张的工厂进化史——工厂模式 一、简单工厂模式&#xff1a;全能生产线二、工厂方法模式&#xff1a;分品牌代工三、抽象工厂模式&#xff1a;生态产品族四、三种模式核心对比表五、结合Spring实现简单工厂&#xff08;实践&#xff09; 小张从华强北起家&#xff0c;最初只有…

C语言,原码、补码、反码

计算机是以补码来存储的 原码&#xff1a;正数最高位为&#xff1a;0&#xff1b;负数最高位为&#xff1a;1 &#xff08;最高位是符号位&#xff09; 正数&#xff1a;三码合一 如&#xff1a;2&#xff1a; 原码&#xff1a;0000 0000 0000 0000 0000 0000 0000 0010&#…

2025年智能合约玩法创新白皮书:九大核心模块与收益模型重构Web3经济范式

——从国库管理到动态激励的加密生态全栈解决方案 一、核心智能合约架构解析 1. 国库合约&#xff1a;生态财政中枢 作为协议的金库守卫者&#xff0c;国库合约通过多签冷钱包与跨链资产池实现资金沉淀。其创新点包括&#xff1a; 储备资产动态再平衡&#xff1a;采用预言机实…

【Android】Android 打包 Release 崩溃问题全解析:Lint 错误、混淆类丢失及解决方法大全

摘要&#xff1a; 在 Android 项目的 Release 打包过程中&#xff0c;经常遇到诸如 Lint 校验失败、程序闪退、类找不到等问题。本文将详细分析 Android 打包时常见的崩溃原因&#xff0c;特别是如何应对 Lint 报错、混淆引发的类丢失&#xff08;NoClassDefFoundError&#xf…

热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索

654.最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大…

【前缀和】矩阵区域和(medium)

矩阵区域和&#xff08;medium&#xff09; 题⽬描述&#xff1a;解法&#xff1a;代码Java 算法代码&#xff1a;C 算法代码&#xff1a; 题⽬描述&#xff1a; 题⽬链接&#xff1a;1314. 矩阵区域和 给你⼀个 m x n 的矩阵 mat 和⼀个整数 k &#xff0c;请你返回⼀个矩阵 …

一周学会Pandas2 Python数据处理与分析-Pandas2读取Excel

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili Excel格式文件是办公使用和处理最多的文件格式之一&#xff0c;相比CSV文件&#xff0c;Excel是有样式的。Pandas2提…

【MySQL】002.MySQL数据库基础

文章目录 数据库基础1.1 什么是数据库1.2 基本使用创建数据库创建数据表表中插入数据查询表中的数据 1.3 主流数据库1.4 服务器&#xff0c;数据库&#xff0c;表关系1.5 MySQL架构1.6 SQL分类1.7 存储引擎1.7.1 存储引擎1.7.2 查看存储引擎1.7.3 存储引擎对比 前言&#xff1a…

02-redis-源码下载

1、进入到官网 redis官网地址https://redis.io/ 2 进入到download页面 官网页面往最底下滑动&#xff0c;找到如下页面 点击【download】跳转如下页面&#xff0c;直接访问&#xff1a;【https://redis.io/downloads/#stack】到如下页面 ​ 3 找到对应版本的源码 https…

大模型上下文协议MCP详解(1)—技术架构与核心机制

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. MCP概述 1.1 定义与目标 MCP(Model Context Protocol,模型上下文协议)是由Anthropic公司于2024年11月推出的开放标准协议。它旨在解决AI大模型与外部工具、数据源及API之间的标准化交互问题…

Windows下安装depot_tools

一、引言 Chromium和Chromium OS使用名为depot_tools的脚本包来管理检出和审查代码。depot_tools工具集包括gclient、gcl、git-cl、repo等。它也是WebRTC开发者所需的工具集&#xff0c;用于构建和管理WebRTC项目。本文介绍Windows系统下安装depot_tools的方法。 二、下载depo…

解决 vite.config.ts 引入scss 预处理报错

版本号&#xff1a; "sass": "^1.86.3","sass-loader": "^16.0.5","vite": "^6.2.0" 报错1&#xff1a;[plugin:vite:css] [SASS] Error&#xff1a;Cant find stylesheet to import vite.config.ts 开始文件错…

MySQL学习笔记7【InnoDB】

Innodb 1. 架构 1.1 内存部分 buffer pool 缓冲池是主存中的第一个区域&#xff0c;里面可以缓存磁盘上经常操作的真实数据&#xff0c;在执行增删查改操作时&#xff0c;先操作缓冲池中的数据&#xff0c;然后以一定频率刷新到磁盘&#xff0c;这样操作明显提升了速度。 …