1、问题:力扣原题
2、分析
根据题意展开分析,爬第一层楼梯有一种方法,爬到第二层楼梯有两种方法,那么爬到第三层楼梯可以通过从第一层楼梯一次性跨两步到第三层或者从第二层楼梯一次跨一步到第三层。所以到第三层楼梯的状态可以由第一层楼梯和第二层楼梯的状态进行推导,,故该题可采用dp来实现。
dp五部曲:
1) 确定dp数组及含义
dp[i]表示爬到第i层楼梯总的方法数
2)确定递推公式
dp[i]= dp[i-1] + dp[i-2];
dp[i-1]表示爬到第i-1层有dp[i-1]种方法可行,那么再往上走一步就到第i层楼梯;
dp[i-2]表示爬到第i-2层有dp[i-2]种方法可行,那么再往上走2步就到第i层楼梯;
3)初始化dp
dp[0]=1;dp[1]=1;dp[2]=2;
4)确定遍历顺序
从递推公式中可以看出,遍历顺序一定是从前向后遍历的,因为只有前面的知道了 才可以计算后面的结果。
3、代码:
class Solution {
public int climbStairs(int n) {
if(n<=1) return n;
int[] dp = new int[n+1];
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
}
------------------------------------------------------------------------------------------------------------
问题进阶:最小花费爬楼梯
1、题目:力扣原题
2、题目分析:
每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯,所以示例1中只花费一个15 就可以到阶梯顶,最后一步可以理解为 不用花费。
dp五部曲:
1)确定dp数组以及下标的含义
dp[i]: 到达第i个台阶所花费的最少体力为dp[i]**。(注意这里认为是第一步一定是要花费)
2)确定递推公式:
可以有两个途径得到dp[i],一个是dp[i-1] 一个是dp[i-2],因为存在体力花费,那么选择从dp[i-1]还是dp[i-2]到第i层台阶尼? 为保证花费最少,所以应该选择min(dp[i-1] ,dp[i-2] )+cost[i]
>>注意,加cost[i],而不是cost[i-1],cost[i-2]之类的**,因为题目中说了:每当你爬上一个阶梯你都要花费对应的体力值
3)dp数组初始化
dp[0] = cost[0];
dp[1] = cost[1];
4)遍历顺序:
从前往后
3、代码:
class Solution {
public int minCostClimbingStairs(int[] cost) {
if(cost==null||cost.length==0){
return 0;
}
if(cost.length==1){
return cost[0];
}
int [] dp = new int[cost.length];
dp[0]=cost[0];
dp[1]=cost[1];
for(int i=2;i<cost.length;i++){
dp[i]=Math.min(dp[i-1],dp[i-2])+cost[i];
}
//最后一步,如果是从倒数第二步爬,则最后一步的体力花费可以不用算
return Math.min(dp[cost.length-1],dp[cost.length-2]);
}
}