【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;
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

暴雨推出X705显示器:23.8英寸100Hz IPS屏

IT资讯 6月 7 日消息&#xff0c;日前&#xff0c;暴雨发布了一款 23.8 英寸 IPS 显示器&#xff0c;直屏、支持 100Hz 刷新率。 据官方介绍&#xff0c;X705 显示器分辨率为 19201080&#xff0c;亮度为 300 尼特&#xff08;典型值&#xff09;&#xff0c;对比度 1000:1&…

Junit(Java单元测试)

目录 配置文件 注解 Test 标注测试方法 BeforeAll 和 AfterAll 标注在测试之前和之后执行的方法 BeforeEach 和 AfterEach 标注在每条测试之前和之后执行的方法 TestMethodOrder 和 Order(优先级) 标注测试方法的执行顺序 ParameterizedTest 将测试方法参数化 ValueSou…

【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现(附源码)(下篇)

作者&#xff1a;后端小肥肠 上篇&#xff1a;【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现&#xff08;上篇&#xff09;_spring security activiti7-CSDN博客 目录 1.前言 2. 核心代码 2.1. 流程定义模型管理 2.1.1. 新增流程定义模型数据 …

转让北京劳务分包地基基础施工资质条件和流程

地基基础资质转让流程是怎样的?对于企业来说&#xff0c;资质证书不仅是实力的证明&#xff0c;更是获得工程承包的前提。而在有了资质证书后&#xff0c;企业才可以安心的准备工程投标&#xff0c;进而在工程竣工后获得收益。而对于从事地基基础工程施工的企业&#xff0c;需…

10.1 Go Goroutine

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

基于STM32开发的智能农业监控系统

目录 引言环境准备智能农业监控系统基础代码实现&#xff1a;实现智能农业监控系统 4.1 土壤湿度传感器数据读取4.2 温湿度传感器数据读取4.3 水泵与风扇控制4.4 用户界面与数据可视化应用场景&#xff1a;农业环境监测与管理问题解决方案与优化收尾与总结 1. 引言 随着智能…

【文末附gpt升级秘笈】AI热潮降温与AGI场景普及的局限性

AI热潮降温与AGI场景普及的局限性 摘要&#xff1a; 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;AI热一度席卷全球&#xff0c;引发了广泛的关注和讨论。然而&#xff0c;近期一些学者和行业专家对AI的发展前景提出了质疑&#xff0c;认为AI热潮将逐渐…

BIOPLUSS引领膳食行业创新、整合与再造

2024年NHNE如期而至&#xff0c;同时今年也是中挪建交70年周年&#xff0c;BIOPLUSS作为挪威品牌代表也参加了此次NHNE国际健康营养博览会&#xff0c;此次NHNE展会吸收了来自30多个国家及地区的1200多家品牌参与&#xff0c;BIOPLUSS同时受挪威领事馆、挪威创新署邀请&#xf…

Chapter 6 Frequency Response of Amplifiers

Chapter 6 Frequency Response of Amplifiers 这一节我们学习单极和差分运放的频率响应. 6.1 General Considerations 我们关心magnitude vs 频率, 因此有低通, 带通, 高通滤波器 6.1.1 Miller Effect Miller’s Theorem 考虑impedance Z1和Z2, X和Y之间增益为Av. Z1 Z/(…

C语言 图形化界面方式连接MySQL【C/C++】【图形化界面组件分享】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一.配置开发环境 二…

为什么选择海外服务器?

如何选择跨境电商服务器&#xff1a;详细指南 选择合适的服务器是跨境电商企业成功的基础。服务器的性能和稳定性直接影响着网站的访问速度、用户体验和安全性&#xff0c;进而影响着企业的销量和利润。那么&#xff0c;跨境电商企业该如何选择服务器呢&#xff1f; ​​​​​…

【微信小程序】事件传参的两种方式

文章目录 1.什么是事件传参2.data-*方式传参3.mark自定义数据 1.什么是事件传参 事件传参:在触发事件时&#xff0c;将一些数据作为参数传递给事件处理函数的过程&#xff0c;就是事件传参 在微信小程序中&#xff0c;我们经常会在组件上添加一些自定义数据&#xff0c;然后在…

0元白嫖阿里云4G内存云服务器——感谢伟大的CSDN和阿里云

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对博主首页也很感兴趣o (ˉ▽ˉ&#xff1b;) 学生邮箱白嫖/免费安装JetBrains全家桶(IDEA/pycharm等) —— 保姆级教程-CSDN博客 目录 1、学生认证领取300元优惠券 ​2、购买云服务器 1、学生认证领取…

车载电子电气架构 - 智能座舱基础技术

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

STM32CubeIDE使用过程记录

最近在做一款机器人的开发&#xff0c;使用到了STM32CubeIDE&#xff0c;这里记录一些使用技巧方便后续查阅。 STM32CubeIDE使用过程记录 快捷键开启代码自动补全功能看门狗设置CRC设置IO口取反定时器设置 及 定时器中断外部中断GPIO配置STC15单片机GPIO模式配置片内闪存&#…

【Python教程】3-控制流、循环结构与简单字符串操作

在整理自己的笔记的时候发现了当年学习python时候整理的笔记&#xff0c;稍微整理一下&#xff0c;分享出来&#xff0c;方便记录和查看吧。个人觉得如果想简单了解一名语言或者技术&#xff0c;最简单的方式就是通过菜鸟教程去学习一下。今后会从python开始重新更新&#xff0…

frida hook微信防撤回(PC端)

PC端&#xff1a; 微信的主要功能都是在WeChat\[3.9.10.27]\WeChatWin.dll动态链接库中实现的 直接进IDA分析 都没有符号表 我们需要找一下实现撤回功能的函数&#xff0c;尝试在字符串里搜索revokeMsg 也是有非常多的字符串 我们需要用frida来hook这些字符串来找出撤回实际…

初识volatile

volatile&#xff1a;可见性、不能保证原子性(数据不安全)、禁止指令重排 可见性&#xff1a;多线程修改共享内存的变量的时候&#xff0c;修改后会通知其他线程修改后的值&#xff0c;此时其他线程可以读取到修改后变量的值。 指令重排&#xff1a;源代码的代码顺序与编译后字…

【学习】DCMM认证提升企业竞争优势的表现

DCMM认证是企业提升数据管理能力的重要途径。它不仅可以帮助企业评估自身的数据管理水平&#xff0c;还可以为企业提供改进的方向和目标。在数字化时代&#xff0c;拥有强大的数据管理能力是企业成功的关键。因此&#xff0c;通过DCMM认证&#xff0c;企业可以更好地适应数字化…

ARM交叉编译

目录 一、介绍 1、本地编译 2、交叉编译 二、交叉工具链 1、概念 2、工具 3、获取方法 三、交叉编译运行程序 1、pc机操作&#xff08;x86_64&#xff09; ​2、开发板操作&#xff08;ARM&#xff09; 一、介绍 1、本地编译 本地编译是在与目标运行环境相同的机器上…