递归算法实例应用(四)

爬楼梯 (POJ 4017)

Description

树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数
例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一级,第二次走两级
也可以第一次走两级,第二次走一级,一共3种方法。

Input

输入包含若干行,每行包含一个正整数N,代表楼梯级数,1 <= N <= 30

Output

不同的走法数,每一行输入对应一行输出

Sample Input

5
8
10

Sample Output

8
34
89

算法思想:

首先,假设n充分大时,从分析第一步应如何走开始,第一步可以分为两种情况,即上一层台阶和上两层台阶;接下来考虑第二步应该怎么走,第二步与第一步一样也是可以分为两种情况,但是剩余台阶数相比于第一步减少了一层或两层;第三步同理,直至某一步时,使得台阶正好走完。

从上面分析可知,随着每一步的走法确定之后,问题规模的台阶数就会变少一层或两层。所以该问题就是一个非常明显的用递归将问题规模分解为规模更小的子问题进行求解的问题。

那么该问题的递归公式可以表示为:
n 级台阶的走法 = 先走 1 级后 n − 1 阶台阶的走法 + 先走 2 级后 n − 2 级台阶的走法 n级台阶的走法 = 先走1级后n-1阶台阶的走法 + 先走2级后n-2级台阶的走法 n级台阶的走法=先走1级后n−1阶台阶的走法+先走2级后n−2级台阶的走法
接下来考虑递归的终止条件,输入数据规模为1 <= N <= 30,通过递归公式的逐层递归推导,可以发现几种不同的终止情况
f ( n ) = { 0 , n < 0 1 , n = 0 (1) f(n)= \begin{cases} 0,& n<0 \\ \\ 1,& n=0 \\ \end{cases}\tag1 f(n)=⎩ ⎨ ⎧​0,1,​n<0n=0​(1)
对于每一个n,要么由上一层的N-1而来,要么由N-2而来:

  • 当n<0时,说明上一层的N-1或N-2的走法不成立,所以应返回0,表明不可行,即N-1或N-2有0种走法。
  • 当n=1时,说明上一层N-1或N-2走法使得仅剩下一层台阶要走,所以应仅有一种走法,即一步一个台阶。

f ( n ) = { 1 , n = 1 1 , n = 0 (2) f(n)= \begin{cases} 1,& n=1 \\ \\ 1,& n=0 \\ \end{cases}\tag2 f(n)=⎩ ⎨ ⎧​1,1,​n=1n=0​(2)

同理,对于每一个n,要么由上一层的N-1而来,要么由N-2而来:

  • 当n=0时,说明上一层的N-1或N-2的走法正好走完整个楼梯,所以该层已经不需要走了,故应返回0。
  • 当n=1时,说明上一层N-1或N-2走法使得仅剩下一层台阶要走,所以应仅有一种走法,即一步一个台阶。

f ( n ) = { 1 , n = 1 2 , n = 2 (3) f(n)= \begin{cases} 1,& n=1 \\ \\ 2,& n=2 \\ \end{cases}\tag3 f(n)=⎩ ⎨ ⎧​1,2,​n=1n=2​(3)

同理,对于每一个n,要么由上一层的N-1而来,要么由N-2而来:

  • 当n=1时,说明上一层N-1或N-2走法使得仅剩下一层台阶要走,所以应仅有一种走法,即一步一个台阶。
  • 当n=2时,说明上一层N-1或N-2走法使得仅剩下两层台阶要走,所以应仅有两种走法,即一步一个台阶,或一步两个台阶。

以上便列举了三种不同的终止条件,读者选择一种作为函数终止条件即可。对于终止条件的分析,应从解的递归函数出发,分析其可能终止或异常的几种状态,罗列下终止状态后,判断是否涵盖在此递归函数中所有可能出现的终止或异常状态。因为算法应涵盖在题设的输入条件下,所有可能的解的情况,保证函数的健壮性。


代码逻辑:

本题的递归递归函数和终止条件均较为简单,所以代码逻辑不再赘述。


代码整合:

int main() {//爬楼梯int n;while (scanf("%d", &n)) {//读入每一个输入数据printf("%d\n", Stairs(n));//每读入一个数据就输出该问题规模下的解}return 0;
}int Stairs(int n) {//终止条件if (n < 0)return 0;if (n == 0)return 1;//递归公式return Stairs(n - 1) + Stairs(n - 2);
}

放苹果 (POJ 1664)

Description

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

Input

第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

Output

对输入的每组数据M和N,用一行输出相应的K。

Sample Input

1
7 3

Sample Output

8

算法思想:

由题设输入可分为两种情况,

  1. 盘子数n > 苹果数m,此时必定至少有n-m个盘子为空,所以问题规模此时就变为将n个苹果放在n个盘子里。
  2. 盘子数n ≤ 苹果数m,此时苹果有两种放法:
    • 有空盘放法

      • 若有一个空盘,则问题规模变为,将m个苹果放在n-1个盘子里
      • 若有两个空盘,则问题规模变为,将m个苹果放在n-2个盘子里
      • 若有…个空盘,则问题规模变为,将m个苹果放在…个盘子里
      • 若有n-1个空盘,则问题规模变为,将m个苹果放在1个盘子里
    • 无空盘放法
      • 把n个盘子各放一个苹果,再将剩余的m-n个苹果放在n个盘子里,问题规模再次缩减,此时剩余的m-n个苹果可以在n个盘子里随便放。
    • 所以,综上当盘子数≤苹果数时,放法个数为又空盘放法与无空盘放法之和。

从以上分析可知,该问题也是一个用递归将问题规模分解为规模更小的子问题进行求解的问题。

若用f(m,n)表示m个苹果放在n个盘子里的放法,那么该问题的递归公式可以表示为:
f ( m , n ) = { f ( m , m ) , n > m f ( m , n − 1 ) + f ( m − n , n ) , n ≤ m (1) f(m,n)= \begin{cases} f(m,m),& n>m \\ \\ f(m,n-1)+f(m-n,n),& n\le m \\ \end{cases}\tag1 f(m,n)=⎩ ⎨ ⎧​f(m,m),f(m,n−1)+f(m−n,n),​n>mn≤m​(1)
接下来考虑递归的终止条件,通过递归公式的逐层递归推导,可以发现几种不同的终止情况
f ( m , n ) = { 1 , m = 0 0 , n = 0 (2) f(m,n)= \begin{cases} 1,& m=0 \\ \\ 0,& n=0 \\ \end{cases}\tag2 f(m,n)=⎩ ⎨ ⎧​1,0,​m=0n=0​(2)
即,当盘子数为0时,没有放法可以盘子题设要求,故解为0,当苹果数为0时,只有每个盘子都不放苹果这一种解法。

而且苹果为0时的边界优先级较盘子为0时的边界判定更高!


代码逻辑:

本题的递归递归函数和终止条件均较为简单,所以代码逻辑不再赘述。


代码整合:

int main() {//放苹果int m, n, count;scanf("%d", &count);while (count--) {scanf("%d%d", &m, &n);printf("%d\n", SetApple(m, n));//每读入一组数据就输出该问题规模下的解}return 0;
}int SetApple(int m, int n) {if (n > m) {return SetApple(m, m);//盘子数大于苹果数,简化问题规模}if (m == 0) {//苹果数为0,只有一种全不放的放法,到达递归终止点return 1;}if (n == 0) {//盘子数为0,此时无解,到达递归终止点return 0;}//当盘子数≤苹果数时,为有空盘子放法与无空盘子放法之和return SetApple(m, n - 1) + SetApple(m - n, n);
}

B y ⋯ S s 1 T w o ⋯ 2023 / 01 / 17 By\cdots Ss1Two\cdots2023/01/17 By⋯Ss1Two⋯2023/01/17

递归算法实例应用(四)相关推荐

  1. C语言库函数大全及应用实例十四

    原文:C语言库函数大全及应用实例十四                                       [编程资料]C语言库函数大全及应用实例十四 函数名: strset 功 能: 将一个串 ...

  2. 【Nginx那些事】nginx配置实例(四)搭建高可用集群

    [Nginx那些事]nginx配置实例(四)搭建高可用集群 nginx 实现高可用 安装keepalived keepalived配置 主Nginx服务器配置 从nginx服务器配置 脚本文件权限设置 ...

  3. 转:让程序只运行一个实例的四种方法

    先留着以后有用. 让程序只运行一个实例的四种方法 综述:让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建前,有窗口的程序在窗口创建前,检查系统中是否已经设置了某些特定标志了,如果 ...

  4. java中的递归算法_java递归算法实例分析

    递归算法设计的基本思想是: 对于一个复杂的问题,把原问题分解为若干个相对简单类同的子问题,继续下去直到子问题简单到能够直接求解,也就是说到了递推的出口,这样原问题就有递推得解. 在做递归算法的时候,一 ...

  5. 数据结构基础 之 递归算法实例讲解

    在数学与计算机科学中,递归是指在函数的定义中使用函数自身的方法. 递归算法是一种直接或者间接地调用自身算法的过程.在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易 ...

  6. 递归算法实例应用(五)

    递归算法实例应用(五) 算24 (POJ 2787) Description 给出4个小于10的正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式.现在的问题是,是否存在一种方 ...

  7. 递归与递归算法实例(java实现)

    一.递归介绍         递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法.绝大 多数编程语言支持函数的自调用,在这些 ...

  8. 数学建模预测模型实例(四)---食堂菜品推荐系统

    数学建模预测模型实例(四)-食堂菜品推荐系统 数学建模预测模型实例(一)-大学生体测数据模型 数学建模预测模型实例(二)-表白墙影响力量化模型 python预测算法-线性回归 数学建模预测模型实例(三 ...

  9. activiti自己定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义

    注:(1)环境搭建:activiti自己定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建         (2)创建流程模型:activiti自己定义流程之Spr ...

最新文章

  1. 求助!!让我郁闷纠结恨的状况!!!
  2. 运算符重载:即为函数
  3. rhel5.8安装oracle10g,RHEL 5.8 安装Oracle 10g r2 clusterware 报错
  4. 灾难 BZOJ 2815
  5. socket编程介绍
  6. 小学奥数 7828 最大公约数与最小公倍数 python
  7. Test 2018-07-19 二中集训
  8. 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 TaskMasger 启动
  9. Java软件低级错误:短路运算和非短路运算的区别
  10. 用JCreator编写java程序
  11. 台式计算机如何双屏显示,电脑怎么分屏?|台式电脑双显示器连接方法
  12. mac系统我的世界服务器,我的世界Mac版怎么联机?
  13. modelsim 波形设置显示时间单位
  14. deepin,真好用-09-deepin真垃圾
  15. RabbitMQ(五) | MQ集群搭建、部署、仲裁队列、集群扩容
  16. python打印文档添加条码_使用Python在Excel中批量生成条形码
  17. iphone12文件管理连接服务器,iPhone手机打开服务器功能,和Windows电脑互传文件方法...
  18. Javascript通获得国家 城市 国家代号
  19. 用shell打印正三角形_用shell命令绘制三角形
  20. QQ相关(一)【导出所有QQ好友】

热门文章

  1. 艺术聚焦:#DRIVE
  2. 小米手机系统好牛,真是国产系统的佼佼者
  3. android 系统光标,如何定位android系统中光标的位置
  4. python小猴子摘桃子的故事_小猴子摘桃子
  5. linux 命令 置顶,[置顶] Linux命令惯用法
  6. 用Python人工智能识别图片-识别车牌号
  7. Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十六(商品排序,Thymeleaf快速入门,商品详情页的展示)
  8. 2021年中国皮革行业现状分析:销售收入同比增长8.4%[图]
  9. 弘扬岭南画派爱国精神,广州市海珠区文博管理中心等联袂举办爱国名画进校园
  10. Window程序设计(一)