小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?
这个问题的突破口就是找到是怎么产生的这个结果,什么结果? 就是这个最后一步是右脚是怎么产生的,经由这样的产生我们可以通过动态规划算法来去解决这个问题。由问题入手,不是说每一步只能迈上1个或2个台阶吗,而要推出有多少种不同的上法。而约束条件是先迈左脚且最后一步是迈右脚
如果xi:表示符合问题的所有的上法
好,那么我们都够得出如果是只有一个台阶的话是不能满足条件的。即x1=0,那么第二个台阶是通过暴力分析法都够得出x2=1。那么x3?
刚才说过只要能找到问题的突破口,即登上最后的阶梯的这个右脚是怎么产生的呢。这个很简单,是因为xi-1是左脚先迈上的,即前一阶是左脚先迈上的,以及xi-2也是左脚先迈上的,即前第二阶也是左脚先迈上的。为什么呢?
这是因为在这种情况下,直接迈右脚就可以直接到达最后一阶。符合问题的条件。
也就是说x3是要x1的仅是左脚的上法+x2的仅是左脚的上法(仅是左脚的上法意思就是迈上这一阶台阶的时候,是先迈的左脚。我们只考虑在这一阶台阶迈左脚的情况,而不考虑会有迈右脚的情况)
我们通过暴力分析法分析下:
第一阶不用考虑直接迈左脚,所以只有1种上法。
上第二阶,可以通过左脚迈上第一阶,右脚迈上第二阶;左脚跨两阶迈上第二阶,就这两种。而在这种情况下,仅左脚迈上第二阶的是1种,仅右脚(符合问题)的也是1种
而第三阶经由分析能够推出来符合问题就只有2种,满足刚刚得出的假设。
那么接下来如果得到仅左脚的上法。可以仿照上面想的,仅左脚的前提不就是在前一阶或者前第二阶是仅右脚迈上的所有的上发。
所以我们可以这样的得出递推方程:
令x[i]:仅考虑在第i阶的阶梯中右脚的上法(符合问题的,也就是问题所考虑的情况)
y[i]:仅考虑在第i阶的阶梯中左脚的上法
x[i]=y[i-1]+y[i-2]
y[i]=x[i-1]+x[i-2]
然而x[1],x[2],y[1],y[2]都是可以通过问题分析得到。那么从第3阶开始逐步通过动态规划算法来得出,直至第39阶
根据这样的思路来写代码:
package com.lanqiaomain;
/**
* 利用动态规划算法解决此问题,递推方程:
* 仅右脚登上第n阶的总共的次数=第n-1阶仅左脚登上阶梯的次数+第n-2阶仅左脚登上阶梯的次数
* 然而第n阶仅左脚登上阶梯的次数=第n-1阶仅右脚登上阶梯的次数+第n-2阶仅右脚登上阶梯的次数
*
*/
public class Main {
public static void main(String[] args) {
int n=39;
int a[]=new int[n]; //保存仅右脚登上阶梯的次数
int b[]=new int[n]; //保存仅左脚登上阶梯的次数
int num=Stairs(a, b);
System.out.println(num);
}
public static int Stairs(int a[],int b[]) {
a[0]=0;b[0]=1;
a[1]=1;b[1]=1;
for(int i=2;i<a.length;i++) {
a[i]=b[i-1]+b[i-2];
b[i]=a[i-1]+a[i-2];
}
return a[a.length-1];
}
}