C语言入门笔记 第六讲【递归之青蛙跳台阶】

41 篇文章 1 订阅

负一、我的想法

昨天晚上睡前看了一下问题描述,讲的是一只青蛙跳n个台阶,一次可以跳一阶,一次也可以跳两阶,问一共有多少种跳法。

当时我的思路是:

先想了n=1和n=2的情况,

当n=1时,只有一种跳法--即1;

当n=2时,有两种跳--1 1或者2

因为小青蛙一次可以跳1或者2,

所以我想把n=1和n=2的情况作为递归出口。

比如,n=3的情况,就相当于小青蛙跳了一个2,和一个1

并且他们之间是可以有顺序的,

一共两种顺序:

小青蛙先跳一个n=1,再跳一个n=2;

小青蛙先跳一个n=2,再跳一个n=1。

然而,问题出现了,当小青蛙跳n=2时,选择了1 1跳法,

那么此时上述两种顺序跳出来的结果都是1 1 1,

说明有重复。

当n取更大的时候,这种重复更多,我们需要把它减去。

想到这的时候,我就知道,我的想法肯定错了。

递归算法是为了让人好理解,牺牲一部分机器的运行时间,来换取程序的更强可读性。

我这想法已经把自己绕进去了,显然是不可行的。

下面一起来学一学这个问题吧!

【一、思路 中会阐述清楚为什么不会出现重复问题】

零、问题描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法?

一、思路

当n=1时,一共有一种跳法(1)

当n=2时,一共有两种跳法(1,1),(2)

当n>2时,

这里我们以n=3为例:

由于很好枚举,我们直接给出跳法,

一共3种:

(1,1,1)

(1,2)

(2,1)

如果我们去掉跳的第一次,

如(1,1,1)一共跳了3次,去掉第一次跳的1阶,剩下的结果为(1,1)

同理,剩下两种跳法去掉第一次后的结果分别为(2)和(1)。

我们把他们放在一起看一下:

(1,1)

(2)

(1)

再观察:这前两种:(1,1)和(2)不正好是n=2时的跳法吗?

最后一种,也正好是n=1的跳法。

我们再来枚举一下n=4的情况:

(1,1,1,1)

(1,1,2)

(1,2,1)

(2,1,1)

(2,2)

一共五种。

以第一步跳的是1还是2,我们来划上分割线:

(1,1,1,1)

(1,1,2)

(1,2,1)

------分割线-----------上为A段,下为B段

(2,1,1)

(2,2)

然后,我们对A段进行去掉第一步的处理:

(1,1,1)

(1,2)

(2,1)

是n=3的情景。

同理,对B段进行去掉第一步的处理:

(1,1)

(2)

是n=2的情景。

这时候,递归出来了:

n=4可以划分为n=3和n=2两个子问题,而n=3又可以划分为n=2和n=1两个子问题,

也就是说,n=4  -->  n=3 + n=2  -->  n=2 + n=1 + n=2

而n=1和n=2就是我们的初始条件,递归出口,

所以完成了递归。

函数递推式:

本题和斐波那契数列有异曲同工之妙。

回过头来,我们再想想一开始我的想法出现的问题:是否会导致重复?

答案是不会的。

因为我们是以第一步是1还是2来划分子问题,这里的2是一次跳两阶,很明显,第一步已经不一样了,所以不会出现重复的问题。

用概率论的思想就是先分类

分第一步跳1次还是2次两大类

分类用加法;

而对于第一步跳一次的情景,

它又和后面的步骤形成了分步执行问题

分步用乘法。

但是它自身就只有一步,

所以相当于是

f(n) = 1*f(n-1) + 1*f(n-2)。

这里我们就把是否会出现重复问题给讲清楚了。

二、代码实现

int frog_jump(int n)
{
	if (n == 1)
		return 1;
	else if (n == 2)
		return 2;
	else
		return frog_jump(n - 1) + frog_jump(n - 2);

}



int main()
{
	cout << frog_jump(5);
	return 0;
}

本样例代码程序执行结果为8,

测试多组样例,满足题意。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值