递归算法入门

4 篇文章 0 订阅
3 篇文章 0 订阅

个人对于递归的理解

  1. 递归算法,用于解决具有 状态转移边界性 性质的问题。
  2. 状态转移,如果是用数学公式来表示 即 类似 a[n] = a[n - 1]
    即可以通过求解相对简单的前一个问题来解决。
  3. 边界性,即这个问题有最简单问题, 且这个最简单问题有解, 这个就是递归的边界,也可以说是终点。

下面举个例子
是老师上课用过的例子
背景:有一个随机坐座位的电影院,且保证每一排都有人,小明买了票进去便往第 n 排坐下,但是小明不知道这第n排到底是第几排。他可以怎么做呢? 没错,他会去问前面那一排的人,这便是一个状态转移的过程。假设他问了前面的人小亮,会有两种结果 一种是小亮知道自己在第几排,二是小亮不知道自己是第几排,于是便继续往下面问,继续状态转移。 当假设最坏的情况问到第一排的时候,第一排前面没人,一定知道自己是第一排,便告诉第二排的人,以此向下传递。这里面第一排的人就是 终点 也是 边界, 也可以说是 最简单问题

在这里插入图片描述

代码实现

int find(int n) {
	if (n == 1)  return 1;		//如果是边界就返回值
	else return find(n - 1) + 1;	//不到边界就是前一个问题 + 1
}

模板

下面是小班里某个同学问我的一道问题,直接拿来当模板讲了
在这里插入图片描述
此题给了两个边界 n == 0 || n == 1 的情况,也给了状态转移方程。

可以得到下面的函数

int fun(int n, int x) {
	//此函数有两个边界,遇到边界直接返回
	if (n == 0) return 1;
	if (n == 1) return x;
	//当不是边界时,根据题目给的 状态转移方程 写递归
	if (n >= 1) return ((2 * n - 1) * x) - fun(n - 1, x) - (n - 1) * (fun(n - 2, x)) / n;
	return 0; //不合法输入
}

拓展例题(递归入门了的同学看)

未名湖边的烦恼

一道比较简单的蓝桥杯题目

问题描述
每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。 每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)

输入
两个整数,表示m和n

输出
一个整数,表示队伍的排法的方案数。

输入例子 1

3 2
输出例子 1

5

实现代码

#include<stdio.h>

int fun(int m, int n) {
	if (m < n) return 0;		//当借鞋的人比还鞋还多时,没有方案
	//剩下的都是 m >= n 的情况
	if (n == 0)  return 1; //因为 m >= n,所以n 为 0 的时候,没有人借鞋,自然就只有一种方案  
	return fun(m - 1, n) + fun(m, n - 1); 
}

int main() {
	int m, n;
	scanf("%d%d", &m, &n);
	printf("%d", fun(m, n));
	return 0;
}


状态转移拉出来讲

fun(m - 1, n) + fun(m, n - 1); 

为什么fun(m, n) 会 等于 这两个状态的和呢?

假设 m = 3, n = 2 , 即人数为5, 它的子状态是人数为4的时候,可以理解成排队过程,且第五个人有可能是借鞋也有可能是还鞋,所以是两种子状态的和。
在这里插入图片描述
以上就是递归算法入门的总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值