递归算法实例应用(四)

简介: 递归算法实例应用(四):(POJ 4017)爬楼梯、(POJ 1664)放苹果

递归算法实例应用(四)

爬楼梯 (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级台阶的走法

接下来考虑递归的终止条件,输入数据规模为1 <= N <= 30,通过递归公式的逐层递归推导,可以发现几种不同的终止情况

f(n)=0,n<0

f(n)=1,n=0

对于每一个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
f(n)=1,n=0

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

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

f(n)=1,n=1
f(n)=2,n=2

同理,对于每一个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)= \begin{cases} f(m,m),& n>m \\ \\ f(m,n-1)+f(m-n,n),& n\le m \\ \end{cases}\tag1 $$

接下来考虑递归的终止条件,通过递归公式的逐层递归推导,可以发现几种不同的终止情况

$$ f(m,n)= \begin{cases} 1,& m=0 \\ \\ 0,& n=0 \\ \end{cases}\tag2 $$

即,当盘子数为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);
}


By Ss1Two 2023/01/17

目录
相关文章
|
2月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
50 3
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的优化算法及其应用
【10月更文挑战第8天】 本文将探讨深度学习中常用的优化算法,包括梯度下降法、Adam和RMSProp等,介绍这些算法的基本原理与应用场景。通过实例分析,帮助读者更好地理解和应用这些优化算法,提高深度学习模型的训练效率与性能。
170 63
|
1月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
32 0
|
2月前
|
存储 算法 搜索推荐
这些算法在实际应用中有哪些具体案例呢
【10月更文挑战第19天】这些算法在实际应用中有哪些具体案例呢
44 1
|
2月前
|
机器学习/深度学习 人工智能 算法
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
92 0
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
|
2月前
|
算法 安全 物联网
如何应用SM2算法进行身份认证
【10月更文挑战第5天】如何应用SM2算法进行身份认证
104 1
|
2月前
|
存储 算法 安全
SM2算法的应用场景有哪些?
【10月更文挑战第5天】SM2算法的应用场景有哪些?
130 1
|
2月前
|
存储 算法 安全
Python 加密算法详解与应用
Python 加密算法详解与应用
37 1
|
2月前
|
机器学习/深度学习 算法
深度学习中的优化算法及其应用
本文探讨了深度学习中常用的优化算法,包括梯度下降、随机梯度下降、动量方法和Adam方法。通过对比这些算法的优缺点及适用场景,帮助读者更好地理解和应用这些优化方法。
36 2
|
2月前
|
监控 算法 数据挖掘
HyperLogLog算法有哪些应用场景呢
【10月更文挑战第19天】HyperLogLog算法有哪些应用场景呢
19 0