有限制的楼梯攀登 | 豆包MarsCode AI刷题

84 阅读2分钟

题面:

image.png


主要逻辑:

刷过爬楼梯的原题的童鞋们都知道,本题和原题的区别其实就是有了一步限制,就是在前一步如果是爬两步的话,这一步就不能爬两步,因此,我们在明确dp数组的定义的时候就应该要想到再用一个量来表示这个状态。

dp数组含义:

我们使用一个二维数组 dp[i][j] 来表示走到第 i 层楼梯时,上一步是走了 j 步的总走法数。通过这个数组,我们可以逐步推导出走到每一层楼梯的不同走法数。

递推公式:

本题中的状态转移需要由前面的状态来决定,你爬到第i阶取决于第i-1阶和第i-2阶,但由于限制,所以最后的转移应当分开讨论.

dp[i][1] = dp[i - 1][2] + dp[i -1][1];
dp[i][2] = dp[i -2][1];

初始化:

首先要处理的就是第0个楼梯的时候有多少种走法,这里有一点需要理解的,按照走法的定义,我们不论怎么样都是需要一步才能到达这第0个楼梯.

 dp[0][1] = 1;
 dp[0][2] = 1;
 dp[1][1] = 1;
 dp[1][2] = 1;

遍历顺序:

由于我初始化时候已经带上了1,所以i直接从2开始遍历即可,主要是清楚这个遍历方向的从前往后是有状态的转移决定的。

 for(int i = 2; i <= n; i++){
            dp[i][1] = dp[i - 1][2] + dp[i -1][1];
            dp[i][2] = dp[i -2][1];
 }

最终结果:

通过状态转移,我们可以计算出走到第 n 层楼梯的总走法数,这里要注意的是,需要比较最后一层的时候,那个一个状态的走法最大,因此直接输出比较后的结果即可:Math.max(dp[n][2], dp[n][1])。

整体代码呈现:

public static int solution(int n) {
        // Edit your code here
        //两种状态
        int dp[][] = new int[n+1][3];
        dp[0][1] = 1;
        dp[0][2] = 1;
        dp[1][1] = 1;
        dp[1][2] = 1;
        for(int i = 2; i <= n; i++){
            dp[i][1] = dp[i - 1][2] + dp[i -1][1];
            dp[i][2] = dp[i -2][1];
        }

        return Math.max(dp[n][2], dp[n][1]);
    }

总结:

本题主要是考察大家动态规划对状态的思考,第一个难点就在于dp数组的定义,第二个难点在于想清楚这个i=0的时候这里需要初始化成什么,这里的状态转移反而是比较容易的,与原来的爬楼梯相比也是再考察了大家的分类讨论的思想,代码简单,但是里面的思想还是挺多的。