小青蛙跳台阶

 

小青蛙跳台阶

今天,要讲的是小青蛙跳台阶。

题目1:一只青蛙一次可以跳到一级台阶,也可以跳到二级台阶。求青蛙🐸跳上一个n级台阶总共有几种跳法?

递归方法

分析:如果台阶只有一级台阶的话,那么青蛙只有一种跳法;如果有两级台阶的话,有两种跳法,一种是一次跳一级,另一种是一次跳两级;如果有三级台阶的话,青蛙第一次可以跳一级,剩下的两级可以按照上面提到的跳两级台阶的跳法,若青蛙在跳三级的时候,第一次二级的话,剩下的一级只能按一级台阶的跳法来跳。以此类推,n级台阶与三级台阶的跳法思路一样。

现在我们要求跳n级台阶,有几种跳法

把n级台阶看成n的函数,记为ret(n)

台阶数     ret(n)

1                        ret(1)=1

2                        ret(2)=2

3                        ret(3)=ret(1)+ret(2)

4                        ret(4)=ret(3)+ret(2)

....                       ....

n                         ret(n)=ret(n-1)+ret(n-2)

代码实现

#include<stdio.h>
int ret(int n)
{
	if (n == 1)
		return 1;
	else if (n == 2)
		return 2;
	else
		return ret(n - 2) + ret(n - 1);

}
int main()
{
	int n;
	printf("请输入一个台阶数:");
	scanf("%d", &n);
	int sum=ret(n);
	printf("小青蛙共有%d种跳法\n", sum);
	return 0;
}

迭代方法

如果n==100的时候,那么上面这个代码就不好计算了,因此我们可以使用迭代的算法来计算。

代码实现

#include<stdio.h>
int ret(int n)
{
	int n1 = 1;
	int n2 = 2;
	int total = 0;
	if (n == 1)
		return 1;
    if (n == 2)
		return 2;
	for (int j = 3;j <= n; j++)
	{
		total = n1 + n2;
		n1 = n2;
		n2 = total;
	}
	return total;
}
int main()
{
	int n;
	printf("请输入一个台阶数:");
	scanf("%d", &n);
	int sum=ret(n);
	printf("#include<stdio.h>
int ret(int n)
{
	if (n == 1)
		return 1;
	else
		return 2 * ret(n - 1);
}
int main()
{
	int n;
	printf("请输入一个台阶数:");
	scanf("%d", &n);
	int sum = ret(n);
	printf("小青蛙共有%d种跳法\n", sum);
	return 0;

}
	return 0;
	
}

我们把n等于100输进去,


  看!!!出现负数了,这是因为结果已经超出int类型了

那如果题目变成这样子的呢?我们又该怎么解决它呢?

题目2:一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶,也可以跳上三级台阶,以此类推,四级,五级......也可以跳到n级,那请问跳到n级台阶的话总共有几种跳法呢?

【注】用ret(n)表示小青蛙跳上n级台阶的跳法,给ret(0)=1

分析:

当ret(1)的时候,显然只有一种跳法,即ret(1)=1,当ret(2)的时候,第一种是一次跳到一级,还剩1个台阶,有ret(1)种跳法;第二种是,一次跳到两级,就可以跳完,还有0个台阶,有ret(0)种跳法。当n=3的时候,第一种是第一次跳到一级,剩下两个台阶有ret(2)种跳法,第二种的是,一次跳到两级 ,剩下的一个台阶有ret(1)种跳法;第三种是一次跳到三级,剩下有ret(0)种跳法。当n级台阶的时候,若第一次跳到一级,有ret(n-1)种跳法;若第一次跳到两级,有ret(n-2)种跳法.........若第一次跳到n级台阶,有ret(n-n)种跳法。

台阶数         跳法

1                   ret(1)=1

2                   ret(2)=ret(1)+ret(0)=2

3                    ret(3)=ret(2)+ret(1)+ret(0)=4

...                    ...

n                     ret(n)=ret(n-1)+ret(n-2)+......+ret(n-n)

分析:  ret(n)=ret(n-1)+ret(n-2)+......+ret(n-n)大家可以把它认为是:ret(n)=ret(0)+ret(1)+........ret(n-1)

那么ret(n-1)=ret(0)+ret(1)+ret(2)+.......+ret(n-2)

把ret(n-1)代入到ret(n)中,发现了ret(n)=2*ret(n-1)   (n>1)是由ret(n)-ret(n-1)=ret(n-1)推出来的

这样子,经过推理,我们可以很清楚的怎么写这个问题的代码了

代码实现

#include<stdio.h>
int ret(int n)
{
	if (n == 1)
		return 1;
	else
		return 2 * ret(n - 1);
}
int main()
{
	int n;
	printf("请输入一个台阶数:");
	scanf("%d", &n);
	int sum = ret(n);
	printf("小青蛙共有%d种跳法\n", sum);
	return 0;

}

总结

从上面的例子上,我们可以很清楚的了解到递归其实就是重复调用函数自身实现循环。优点就是a.用有限的循环语句实现无限集合;b.代码易于理解;c.大问题转化成小问题。缺点:a.递归不断调用函数,导致浪费空间;b.容易导致堆栈溢出。迭代函数内某段代码实现循环。优点就是a.效率高,代码运行的时间只会随循环的增加而增加,相对于递归的话,它没有额外开销。缺点:a.代码难推理;b.相对于代码它没递归的好理解。写者可以根据利弊来写代码。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值