详解 C语言 青蛙跳台阶问题

目录:

一.问题表述

二.问题分析

采用列举的思考角度

转化为斐波那契数列

递归算法的利弊分析

三.启示

一.问题表述

一只青蛙要跳上一定数量的台阶,但其一次只能跳一阶或两阶,求这只青蛙跳上n上台阶有多少中跳法?

二.问题分析

因为青蛙每次只能跳一个台阶或两个台阶,因此可先对两种比较简单的情况分析:

跳一个台阶毫无疑问只有一种情况:一次跳一个;

跳两个台阶有两种情况:每次跳一个和一次跳两个;

1.采用列举的思考角度

青蛙跳上n个台阶,对青蛙所跳的每一步的所有情况都穷举出来,即可得到一共有多少种跳法。此过程可用递归来完成。以跳上六个台阶为例:(图示)

如图,青蛙每一步的每种情况都被列了出来,最后只要数出最终结果即为

2+1+2+2+1+2+1+2=13(上图中2中还有两种情况,如前文所说)

从上图可以看出每次跳跃无非使得剩余台阶数-1或-2,且易知最终都会回到剩余1个或剩余2个台阶的状况,因此我们可以以这两个情况作为递归算法的两个最终返回情况,即让f(1)=1,f(2)=2。

设这个递归算法的函数为f(x),如图2:

利用递归可让电脑完成上述自己列举,即自己一个个展开再求和的过程,并最终得到返回值。

从这个角度,我们写出代码:

小结:这个是从数学角度,对青蛙每一步所有情况进行列举并统计的方式。

2.转化为类斐波那契数列

青蛙跳一个台阶有一种跳法

青蛙跳两个台阶有两种跳法

青蛙跳三个台阶?

青蛙跳三个台阶,它第一跳无非两种情况:跳一阶和跳两阶

若跳了一阶,则还剩两阶,那么就是跳两个台阶的情况;

若跳了两阶,则还剩一阶,那么就是跳一个台阶的情况;

因此跳三个台阶时相当于先分类再相加前两种情况

即跳三个台阶=跳一个台阶+跳两个台阶。

同理,青蛙跳四个台阶:

若跳了一阶,则还剩三阶,那么就是跳三个台阶的情况;

若跳了两阶,则还剩两阶,那么就是跳两个台阶的情况;

即跳四个台阶=跳两个台阶+跳三个台阶。

再来,青蛙跳五个台阶:

若跳了一阶,则还剩四阶,那么就是跳四个台阶的情况;

若跳了两阶,则还剩三阶,那么就是跳三个台阶的情况;

即跳五个台阶=跳三个台阶+跳四个台阶。

........

既然跳n个台阶的种数可以等于跳n-1个台阶的种数加上跳n-2个台阶的种数,那么可以将这个问题转换为类似斐波那契数列来解决。即n=n-1+n-2

而对于求第n个斐波那契数列的数,我们一般有两种解决方式:递归与迭代

递归方式:

#define _CRT_SECURE_NO_WARNINGS 1 //vs2019为使用scanf函数所用。
#include <stdio.h>
int f(int n)
{
	if (n == 1)
	{
		return 1;
	}
	else if (n == 2)
	{
		return 2;
	}
	else if (n > 2)
	{
		return f(n - 1) + f(n - 2);//递归
	}

}
int main()
{
	printf("青蛙要跳几个台阶=>");
	int a = 0;
	scanf("%d", &a);
	printf("青蛙会有几种跳法=>");
	printf("%d", f(a));

}

其实这个代码与上面所用从列举角度写出的代码一样,但理解方式是不同的。即一种代码的两种不同理解。

迭代方式:

斐波那契数列怎么用循环来解决呢?

我们知道斐波那契无非是前两个数相加等于第三个数,而前一个数又是它的前两个数之和。

那么我们可以这样思考:(如图所示)

图中看出a  +  b  =  c 整体不断往后一个一个数字推移,那么如何让电脑实现这个过程呢?

我们把一个个a  +  b  =  c 整体往后推的同时对整齐,上图可以发现,用一个循环,每次循环让a等于上一次的b,让b等于上一次的c,就可以让a  +  b  =  c 整体抽象地不断往后推,最后输出c的值即可。

(上图所用为常规斐波那契数列,注意我们讨论的青蛙跳台阶问题第二个数应当是2)

那么便可以写出代码:

int f(int n)
{
	int a = 1;
	int b = 2;
	int c = 0;
	while (n > 2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;//每次循环n减1,一直到n<=2时循环停止
	}
	return c;
	if (n <= 2)
	{
		return n;
	}
}
int main()
{
	printf("青蛙要跳几个台阶=>");
	int a = 0;
	scanf("%d", &a);
	printf("青蛙会有几种跳法=>");
	printf("%d", f(a));
	return 0;
}

3.递归算法的利弊分析

递归算法的好处:容易被想到,有一定的公式即很容易写出来;

递归算法的弊端:在此问题中,同一个情况被反复运算了多次,导致其效率低下,在输入较大数值时电脑运算时间延长。

比如下图,计算f(3)的次数

计算机重复计算了大量的f(3),再看下这个图,就明白了

 这幅图中就有两个f(3)随着输入数字的增多f(3)会迅速增多,而且还有其它的数。

计算机在反复运算相同的东西,效率大大下降

与递归不同的是,循环并不是从最后一个数往回层层展开运算,而是从第一个数开始往后一个个推移,因此没有重复现象

 

 效率大大提升

三.启示

解决问题时应当抓住问题的关键。

1.青蛙每次只能跳一个台阶或两个台阶;

2.输入的是台阶数,输出的数有多少种跳法。

3.善于用数学模型解决问题(如列举,转化为斐波那契数列等)

 

 

 

  • 19
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值