爬楼梯问题(一次爬1-n个楼梯,共有几种爬法)

题目:爬楼梯,每次可以爬1个或着2个台阶或者更多个台阶,共有几种爬法。

分析:这种题一般有两种做法,第一种是找规律。第二种是动态规划。

第一种:找规律法

假如题目是每次爬1个或者爬2个。求所有的可能性

首先我们先算出前十个的所有可能结果

台阶个数12345678910
可能情况123581321345589

观察上表不难发现,从第三个台阶开始,当前的台阶数等于前两个数之和。这也就是斐波那契数列,得到这些信息后,编程就很容易了。

public static int F2(int n) {       //输入n个台阶,返回所有种可能
		if(n == 1) return 1;        
		if(n == 2) return 2;
		
		int n1 = 1;                //定义第一节台阶
		int n2 = 2;				   //定义第二节台阶

		for(int i = 0; i < n-2;i++) {  //从第三节台阶开始,当前台阶数等于前两节之和
			int temp = n1 + n2;
			n1 = n2;
			n2 = temp;
		}
		return n2;
	}

假如题目是每次爬1个或者爬2个或者爬3个,求所有的可能数。

同样可以用上面的做法,先找规律。

台阶个数12345678910
可能情况124713244481149274

当然,找到第十个其实是非常麻烦的,一般找到第五个就差不多了。
显然也符合上面的规律,即从第四个数开始,当前数等于前三个数之和。


	public static int F2(int n) {  //输入n个台阶,返回所有的可能数 思想同上
		if(n == 1) return 1;
		if(n == 2) return 2;
		if(n == 3) return 4;
		
		int n1 = 1;
		int n2 = 2;
		int n3 = 4;
		
		for(int i = 0; i < n-3;i++) {
			int temp = n1+n2+n3;
			n1 = n2;
			n2 = n3;
			n3 = temp;
		}
		return n3;
	}

看到这里,之后的每次可以爬4阶、5阶…n阶的做法,都是同一种思路了。

第二种:动态规划

还是上面的第一题,每次可以爬1阶或者2阶,求共有几种爬法。

我们可以倒着推。最后一层台阶可以是从倒数第一层爬一阶楼梯上来的,也可以是从倒数第二层爬两层上来的。同理,倒数第一层台阶可以是从倒数第二阶爬一层上来的,也可以是从倒数第三层爬两层上来的…直到第二层可以从第一层爬一层上来,也可以是从地面爬两层上来。而第一层只能是从地面爬一层上来。
画图再解释一遍。假设n是4。
在这里插入图片描述
红色线表示每次爬一层,蓝色线表示每次爬两层。可以将该题转换成下楼梯,则需要在每层进行判断,当前层能否支持一次下一层,若支持则向下走一层,再判断当前层是否支持一次下两层,若支持,则下两层,若都不支持,则表示已经到地面了。接下来上代码。

public static int F(int n) {   //输入n阶台阶 求所有可能性
		if(n==0) return 1;     //n为0  表示已经到地面了 这条路线就是一种可能性 则返回1
		int sum = 0;          //sum表示所有路线的和
		if(n-1 >= 0) {         //判断当前层能否支持向下走一层
			 sum += F(n-1);    //向下走一层
		}
		if(n-2 >= 0) {        //判断当前层能否支持向下走两层
			sum += F(n-2);    //向下走两层
		}
		return sum;           //返回所有的可能
	}

假如此时题目为:每次爬1个或者爬2个或者爬3个,求所有的可能数。

同理上述操作,我直接画图:
在这里插入图片描述

红色表示爬一层,蓝色表示爬两层,紫色表示爬三层。思想同上直接上代码。

public static int F(int n) {   输入n阶台阶 求所有可能性
		if(n==0) return 1;  
		int sum = 0;
		if(n-1 >= 0) {		//判断当前层能否支持向下走一层
			 sum += F(n-1);
		}
		if(n-2 >= 0) {		//判断当前层能否支持向下走两层
			sum += F(n-2);
		}
		if(n-3 >= 0) {		//判断当前层能否支持向下走三层
			sum += F(n-3);
		}
		return sum;
	}

则之后的每次可以爬n层都是这个思路,代码也大同小异。

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值