【C语言】青蛙跳台阶问题 - 递归算法(一种思路,针对三种不同的情况)

文章目录

  • 1. 前言
  • 2. 题目和分析
    • 2.1 代码实现
    • 2.2 反思 (重点)
  • 3.题目二(变式)
    • 3.1 分析
    • 3.2 代码实现
  • 4. 题目三(变式)
    • 4.1 分析
    • 4.2 代码实现

1. 前言

相信大家看到青蛙跳台阶问题时,第一时间就会想到递归。那你知道为什么会使用递归吗?如果你对此一知半解的话,那么请跟随我的脚步,一起探索递归解决问题背后的秘密。

可能也有的读者会问,我不是学C语言的,看这个会不会不合适。对此,我只想说:编程的尽头是天马行空的脑洞和转化问题的能力,编程语言只是我们解决问题的工具,只要问题被解决了,用什么语言效果都是大差不差的。

那么,话不多说,Let’s go!!!

2. 题目和分析

题目一:一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法。

问题的描述很简单,那我们的破题关键在哪里呢?

我们可以先罗列几种情况,看一下有什么规律。
罗列情况
从这里,你可以发现一个规律:

当只有一个台阶时,青蛙它别无选择,它只需要跳一步就可以了;

当存在两个台阶时,青蛙此时就会有两种方法。
第一种就是,当青蛙选择一开始先跳一步时,那么两个台阶就只剩下一个台阶要跳了,那还能怎么办,继续跳就完事了。
第二种就是,青蛙选择一次跳两步,两个台阶就被跳完了。

当存在三个台阶时,青蛙此时就会有三种方法。
第一种:一步一步地跳。
第二种:先选择跳一步之后 ,再一次跳两步。
第三种:先选择跳两步,最后再跳一步就行。

后面的列举是一样的思路,限于篇幅的原因,这里就不再过多列举了。

看到这里,我们不妨假设,变量n为青蛙要跳的台阶数,函数Fun为计算青蛙台阶的方法个数。

int Fun(int n)
{... //代填写的内容
}

那么根据题目的要求,我们可以知道一个点,就是:Fun(1) = 1,Fun(2) = 2

仔细观察,我们可以发现一个规律:
当台阶数n=3时,Fun(3) = Fun(2) + Fun(1)

为此,我们可以总结出一个递推公式,就是Fun(n) = Fun(n-1) + Fun(n-2) (n>2)。

为此,我们就可以开始写函数了。

2.1 代码实现

#include<stdio.h>
int Fun(int n)
{if (n<=2) //递归退出条件{return n;}else{return Fun(n - 1) + Fun(n - 2);}
}int main()
{int n = 0;scanf("%d", &n);int ret = Fun(n);printf("%d\n", ret);return 0;
}

2.2 反思 (重点)

可能有的读者对这个规律总结的出现,仍然感觉到很诧异。那么我现在就用语言来解释这个递推公式背后的秘密。

我们可以想象一下,当台阶数大于2时:

当台阶数n=3时,聪明的青蛙此时就会说:“那我先跳1个台阶试试看后面的情况。” 既然青蛙已经跳过了1个台阶,那么总的台阶数就还剩2个。而这个问题不就又转换为:跳两个台阶有多少种跳法。
那这里可能有的读者还会提一个问题,如果青蛙先跳2个台阶呢?还会上述的推理过程吗?
其实大致的方向是不变的,就改一下顺序就可以了。为此你就可以理解Fun(n) = Fun(n-1) + Fun(n-2)这个公式的强大之处,它无关你跳的前后顺序。

看到这里,你可能还是不理解上述的语言表述,我就在多举一个例子

那么,当台阶数n=4,又会发生什么情况呢?Fun(4)
一样的解题思路:
当青蛙选择跳1步时,那么台阶就还剩3个,问题不就又转化为:求3个台阶有多少种跳法。Fun(3)
可是这样还不够啊,青蛙也有可能一开始就跳两步,
当青蛙一开始就跳2步,那么台阶就还剩2个,问题不就又转化为:求2个台阶有多少种跳法。Fun(2)
所以,Fun(4) = Fun(3) + Fun(2)

看到这里,我想你已经彻底理解了这个递推公式的精髓所在了。

这里面也蕴含了一种思想:大事化小的思想,这个不正是我们使用递归的核心思想。通过青蛙的每一步选择都会出现看两种不同的结果,但是每种结果的尽头,台阶数最终不是剩下2个就是1个,都会回到递归的退出条件。

3.题目二(变式)

题目二:一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶…,还可以跳上n级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法。

如果你理解上面青蛙跳台阶的思路,那么这道题就不难了。

3.1 分析

这里我就简单分析一下:
与第一道不同的是,青蛙可以这次可以选择跳<=n的步数了,但是,基本的思路是一样的。
图

假设有n个台阶,函数Fun用来计算n个台阶有多少种跳法。
那么,我们就可以得到一个递推公式:
Fun(n) = Fun(n-1) + Fun(n-2) + … + Fun(2) + Fun(1) + 1 ①
Fun(n-1) = Fun(n-2) + Fun(n-3) + … + Fun(2) + Fun(1) + 1 ②

将上述的①和②结合一下:
Fun(n) = Fun(n-1) + Fun(n-1) = 2*Fun(n-1)

3.2 代码实现

#include<stdio.h>int Fun(int n)
{if (n == 1){return 1;}else {return 2*Fun(n - 1);}
}int main()
{int n = 0;scanf("%d", &n);int ret = Fun(n);printf("%d\n", ret);return 0;
}

4. 题目三(变式)

问题三:一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶…,还可以跳上m级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法。

4.1 分析

这道题目又和上一道题目有所不同,这次青蛙最多跳<=m个台阶数。

由上两题总结出的思路,我们可以很快地写出此题的递推公式:
Fun(n) = Fun(n-1) + Fun(n-2) + … + Fun(n-m) ①
Fun(n-1) = Fun(n-2) + Fun(n-3) + … + Fun(n-m-1) ②
将①和②结合一下:
Fun(n) = 2 * Fun(n-1) + Fun(n-m-1) (n>m)
上述的情况是当n>m时发生的,那么当n<=m时呢?
那问题就会转化为题目二的思路了。

4.2 代码实现

int Fun(int n, int m)
{if (n <= 1) //之所以是小于1,是因为m可能会大于n{return 1;}if(n>m){return 2 * Fun(n - 1, m) - Fun(n - m - 1, m);}return 2 * Fun(n - 1, n); //这里的n不要写成m
}int main()
{int n = 0;int m = 0;scanf("%d %d", &n, &m);int ret = Fun(n, m);printf("%d\n", ret);return 0;
}

后面的两道题希望读者们下来可以慢慢的去琢磨。

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

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

相关文章

【免杀】C2远控-Loader加载器-动态API调用

目录 创建后门程序站在杀毒程序立场上对后门进行分析例&#xff1a;动态调用VirtualProtect函数 作用:绕过杀毒对导入表的检测定性 创建后门程序 VS新建项目 回调函数加载Loader #include <Windows.h>unsigned char shellcode[] "";void CallBack() {void* p…

FlashBrowser

本例&#xff1a;windows10 下载FlashBrowser 解决flash失效问题&#xff0c;更换浏览器 https://www.flash.cn/ 下载FlashBrowser浏览器

Redis的缓存击穿、缓存穿透和缓存雪崩是什么?怎么预防?

Redis的缓存击穿、缓存穿透和缓存雪崩是什么&#xff1f;怎么预防&#xff1f; 前言缓存击穿定义解决思路实现加锁设置过期时间Lua脚本刷新锁 缓存穿透定义实现 缓存雪崩定义解决思路 总结 前言 最近在CSDN上看到了一篇博客&#xff0c;Redis缓存击穿、雪崩、穿透&#xff01;…

深入理解Vue3.js响应式系统基础逻辑

如果您觉得这篇文章有帮助的话&#xff01;给个点赞和评论支持下吧&#xff0c;感谢~ 作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者/csdn百万访问前端博主/B站千粉前端up主 此篇文章是博主于2022年学习《Vue.js设计与实现》时的笔记整理而来 书籍&a…

C++:SLT容器-->stack

C:SLT容器--&#xff1e;stack 1. stack容器2. stack 常用接口 1. stack容器 先进后出&#xff0c;后进先出不允许有遍历行为可以判断容器是否为空可以返回元素的个数 2. stack 常用接口 构造函数 stack<T> stk; // stack采用模板类实现&#xff0c;stack对象的默认构造形…

第1期JAVA社招面试经验月报

面经哥专注互联网社招面试经验分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥&#xff5c;面经哥整理了上月30篇面试经历&#xff0c;选取了较为热点高频的面试题供大家参考 基础知识类‍‍‍‍‍ 1、说下双亲委派原则以及类加…

1992-2012年美国西海岸的海面高度异常数据集

Gridded Altimeter Fields with Enhanced Coastal Coverage 具有增强海岸覆盖范围的网格化测高场 简介 具有增强的海岸覆盖范围的网格化高度计场数据产品包含美国西海岸的海面高度异常&#xff08;SSHA 或 SLA&#xff09;以及北纬 35.25 度-48.5 度和东经 227.75 度-248.5 …

Python酷库之旅-开启库房之门

目录 一、库的定义 二、库的组成 三、库的分类 四、如何学好Python库&#xff1f; 五、注意事项 六、推荐阅读 1、Python筑基之旅 2、Python函数之旅 3、Python算法之旅 4、Python魔法之旅 5、 博客个人主页 一、库的定义 在Python中&#xff0c;库(Library)是一个封…

探索智慧机场运营中心解决方案的价值与应用

随着全球航空业的不断发展&#xff0c;机场运营中心的作用日益凸显。智慧机场运营中心解决方案以其高效的管理和智能化的运营模式&#xff0c;成为优化机场运营、提升服务水平的重要工具。本文将深入探讨智慧机场运营中心解决方案的价值与应用&#xff0c;揭示其在机场管理中的…

机器学习常见知识点 2:决策树

文章目录 决策树算法1、决策树树状图2、选择最优决策条件3、决策树算法过程→白话决策树原理决策树构建的基本步骤常见的决策树算法决策树的优缺点 【五分钟机器学习】可视化的决策过程&#xff1a;决策树 Decision Tree 关键词记忆&#xff1a; 纯度、选择最优特征分裂、熵、基…

电脑上的瑞士军刀

一、简介 1、一款专为 Windows 操作系统设计的桌面管理工具&#xff0c;它具备保存和恢复桌面图标位置的功能&#xff0c;使用户能够在各种情况下&#xff0c;如分辨率变动、系统更新或其他原因导致的图标位置混乱后&#xff0c;快速恢复到熟悉的工作环境。它还拥有诸多实用功能…

【Pyqt6 学习笔记】实现串口调试助手,并将接收到数据模拟键盘输出

文章目录 代码示例main.pyscreen_shot_module.pyqrcmd.pyuntitled.pyuntitled.ui 本文内容是 【Pyqt6 学习笔记】DIY一个二维码解析生成小工具的延申&#xff0c;在原来的基础上实现了串口调试助手功能&#xff0c;并利用 pywinauto的 keyboard模块将接收到数据模拟键盘输出…

【递归+二叉树思想+搜索】 Alice and the Cake题解

Alice and the Cake题解 AC记录&#xff1a;记录-洛谷 题面翻译&#xff08;大概就是题目大意&#xff09; 执行恰好 n − 1 n-1 n−1 次操作&#xff0c;每次操作可以选择当前所有蛋糕中满足其重量 w ⩾ 2 w\geqslant 2 w⩾2 的一块&#xff0c;然后将其分为质量分别为 …

手机连接ESP8266的WIFI,进入内置网页,输入要显示的内容,在OLED显示屏上显示文本

连线 OLEDESP8266含义GNDGND地线VCC3V电源SCLD1时钟线SDAD2通信数据线 只支持英文信息的显示和数字。 #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>#d…

5.大模型高效微调(PEFT)未来发展趋势

PEFT 主流技术分类 UniPELT 探索PEFT 大模型的统一框架&#xff08;2022&#xff09; UIUC 和Meta AI 研究人员发表的UniPELT 提出将不同的PEFT 方法模块化。 通过门控机制学习激活最适合当前数据或任务的方法&#xff0c;尤其是最常见的3大类PEFT 技术&#xff1a; Adapters…

事业单位——被逆袭篇

目录 一、结果 二、考试 三、时间 四、复习 五、总结 一、结果 图1&#xff1a;2024年浙江广播电视集团下属浙江省中波发射管理中心公开招聘笔面试结果 准考证号笔试面试总成绩排名备注107016070.866.48310702416555.44107134390.871.681入围107146869.869.08210715406454.…

征信受损,别再犯傻!

听说你的征信出了点小问题&#xff1f;别急&#xff0c;这事儿说大不大&#xff0c;但也不能掉以轻心。征信&#xff0c;说白了就是你借钱还钱的记录本&#xff0c;一旦它“花”了&#xff0c;借钱可就没那么轻松了。 先来说说这征信“花”了是咋回事 征信“花”了&#xff0c…

18.1 HTTP服务器-极简服务器、请求与响应

1. 极简服务器 大道至简。使用Go语言构建世界上最简单的HTTP服务器&#xff0c;仅需四行代码。 标准库的net/http包提供了多种用于创建HTTP服务器的方法&#xff0c;其中包括&#xff1a; http.HandleFunc("/", rootHandler) 第一参数&#xff1a;访问的url 第二…

【Linux】进程间通信之命名管道

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

109.网络游戏逆向分析与漏洞攻防-装备系统数据分析-商店与捨取窗口数据的处理

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 现在的代码都是依据数据包来写的&#xff0c;如果看不懂代码&#xff0c;就说明没看懂数据包…