钰的递归学习笔记

本文深入浅出地介绍了递归的概念,通过汉诺塔、N皇后和上台阶等经典问题,揭示了递归在解决问题时的优雅与效率。递归与循环的区别在于关注结果而非过程。同时,文章还探讨了动态规划,以N皇后问题为例,展示了如何利用递归来实现动态规划。最后,文章以P1287盒子与球问题为结尾,进一步阐述了递归在组合问题中的应用。动态规划和递归在信息技术领域中扮演着重要角色,是算法设计的基础工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归

递归是什么?

程序调用自身就叫做递归,怎么理解?套娃!

https://www.bilibili.com/video/BV13K4y1j7Za

参考这个B站视频

为什么要用递归?

用递归去解决多重循环,杀人于无形

而递归跟循环的区别,循环注重过程,而递归值注重结果

怎么用递归?

分为三步

1.知道递归用来做什么

2.知道递归的结束条件

3.知道递归之间的关系

例题

汉诺塔

#include<bits/stdc++.h>
using namespace std;
int N;
void hanoi(int n,char crt,char mid,char dest)// 干啥,也就是为了把n个块从crt移到dest借助mid 
{
	if(n==1)//结束条件,到此就开始回溯 
	{
		cout<<crt<<"->"<<dest<<endl;
		return ;
	}
	hanoi(n-1,crt,dest,mid);// 把n-1个从crt借助dest移到mid 
	cout<<crt<<"->"<<dest<<endl;
	hanoi(n-1,mid,crt,dest);//把n-1个从mid借助crt移到dest ,下面两步均为递归的关系,即为了满足a->c先要a->b然后b->c 
}
int main()
{
	cin>>N;
	hanoi(N,'a','b','c');
	return 0;
}

 

 

N皇后

要求n个国际象棋的皇后摆在n*n的棋盘上
且相互不能攻击,输出全部方案

输出结果里每一行都代表一种摆法
行里第i个数字代表第i行皇后放在第几列

输入:
4
输出:
2 4 1 3
3 1 4 2

#include<bits/stdc++.h>
using namespace std;
int N;
int queenpos[100];//皇后的位置 
void Nqueen(int k)// 目的,从第k个开始摆,并摆在不冲突的位置 
{
	if(k==N)//结束条件,从此回溯 
	{
		for(int i=0;i<N;i++)
		cout<<queenpos[i]+1<<' ';//因为在数组从0开始,所以+1; 
		cout<<endl;
		return ;
	}
	for(int i=0;i<N;i++)//以下为判断每个的摆放位置,并与下一个产生关联 
	{
		int j;
		for(j=0;j<k;j++)
		{
			if(queenpos[j]==i||abs(queenpos[j]-i)==abs(k-j)) break;//检查第k个放的如果是i位置是不是与前面的有冲突 
		}
		if(j==k)
		{
			queenpos[j]=i;
			Nqueen(k+1);
		}
	}
}
int main()
{
	cin>>N;
	Nqueen(0);//从0开始排,那些从1开始的边界一般是k>n 
	return 0;
}

上台阶

每次走1/2级台阶
n级台阶走法=
1.先走一级后,n-1级台阶走法
2.先走两级后,n-2级台阶走法
f(n)=f(n-1)+f(n-2) n=1(其实这玩意不就是斐波那契吗)

#include<bits/stdc++.h>
using namespace std;
int stairs(int n)// 为了找n个台阶用多少种走法 
{
	if(n<0) return 0;//和下面一样都是终点 
	if(n==0) return 1;//这样的话就没必要特意声明1和2的条件了 
	return stairs(n-1)+stairs(n-2);//关联 
}
int main()
{
	int m;
	while(cin>>m)
	{
		cout<<stairs(m)<<endl;
	}
	return 0;
}

 P1287 盒子与球

题目描述

现有 rr 个互不相同的盒子和 nn 个互不相同的球,要将这 nn 个球放入 rr 个盒子中,且不允许有空盒子。请求出有多少种不同的放法。

两种放法不同当且仅当存在一个球使得该球在两种放法中放入了不同的盒子。

输入格式

输入只有一行两个整数,分别代表 nn 和 rr。

输出格式

输出一行一个整数代表答案。

输入输出样例

输入 #1复制

3 2

输出 #1复制

6

说明/提示

样例输入输出 1 解释

有两个盒子(编号为 1, 21,2)和三个球(编号为 1, 2, 31,2,3),共有六种方案,分别如下:

盒子编号方案 1方案 2方案 3方案 4方案 5方案 6
盒子 11小球 11小球 22小球 33小球 2, 32,3小球 1, 31,3小球 1, 21,2
盒子 22小球 2, 32,3小球 1, 31,3小球 1, 21,2小球 11小球 22小球 33

数据规模与约定

对于 100\%100% 的数据,保证 0 \leq r \leq n \leq 100≤r≤n≤10,且答案小于 2^{31}231。

百度链接 斯特灵数:https://baike.baidu.com/item/%E6%96%AF%E7%89%B9%E6%9E%97%E6%95%B0/4938529?fr=aladdin

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

ll f(int n,int m)
{
	if (m <= 0 || n < m)//(2)递归结束条件
        return 0;
    if (n == m)//(2)递归结束条件 
        return 1;
    else
        return f(n-1, m-1) + f(n-1, m) * m;/*(1)用来干什么(3)递归之间的关系
		 用来模拟放小球,
		 1.第n个小球单独占一个盒子其余n-1个放其
		 他m-1个盒子里
		2.和其他的放一起,先把n-1个安排好,第n个
		可以放在其他m个盒子中的一个*/ 
}

ll fc(int i)
{
	if(i==1) return 1;
	else return i*fc(i-1);
}

int main()
{
	ll n,m;
	cin>>n>>m;
	cout<<f(n,m)*fc(m)<<endl;
	return 0;
}

 

 看这又一篇漫画就是将爬楼梯https://zhuanlan.zhihu.com/p/31628866

他说这就叫动态规划,我后面的内容才是动态规划欸,那我不是超纲了,不不不,后面你会开心的发现,什么动态规划,什么dfs,bfs都是套娃而已。

郭炜老师mooc链接:https://www.icourse163.org/learn/PKU-1001894005?tid=1461679488

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值