文章目錄
- 題目描述
- 簡化題目
- 思路分析
- 完整代碼
題目描述
給你一個整數數組 cost ,其中 cost[i] 是從樓梯第 i 個台階向上爬需要支付的費用。一旦你支付此費用,即可選擇向上爬一個或者兩個台階。
你可以選擇從下标為 0 或下标為 1 的台階開始爬樓梯。
請你計算并傳回達到樓梯頂部的最低花費。
示例 1:
輸入:cost = [10,15,20]
輸出:15
解釋:你将從下标為 1 的台階開始。
支付 15 ,向上爬兩個台階,到達樓梯頂部。
總花費為 15 。
示例 2:
輸入:cost = [1,100,1,1,1,100,1,1,100,1]
輸出:6
解釋:你将從下标為 0 的台階開始。
- 支付 1 ,向上爬兩個台階,到達下标為 2 的台階。
- 支付 1 ,向上爬兩個台階,到達下标為 4 的台階。
- 支付 1 ,向上爬兩個台階,到達下标為 6 的台階。
- 支付 1 ,向上爬一個台階,到達下标為 7 的台階。
- 支付 1 ,向上爬兩個台階,到達下标為 9 的台階。
支付 1 ,向上爬一個台階,到達樓梯頂部。
總花費為 6 。
簡化題目
這題目描述的就很詭異。理清楚花費順序比寫出代碼要難哈哈。
簡單來說,cost = [10,15,20] 題目給了這個數組,樓頂在最後 cost = [10,15,20] X。
也就是我标的X的地方是樓頂,可以從0号或者1号位置開始,每次可以選擇走1步或者2步,走的時候要花費目前數值的體力。
這裡何時花費體力值比較繞,總的來說,第一步必花費體力值,後面到哪裡就直接花掉。
順序步驟:
即 第一步花費 -> 選擇走幾步 -> 到達某個點(直接花費掉該點的體力值)->繼續選擇走幾步 -> 到達某個點(繼續花體力)
且最後一步到達頂點的台階不需要花費體力 這點很重要
比如cost = [10,15,20] 從1号位置開始走兩步,直接能達到X的位置,花費15。為最小花費。
思路分析
動态規劃五步走:
1.确定dp[i]含義;
dp[i] 表示到達第i個台階所要花費的最小體力值。
2.确定遞推公式:
到達第i個台階隻能從i-1邁一步上來,或者從i-2邁兩步上來。顯然選擇花費最小的方案走。
得到遞推公式:
dp[i] = min(dp[i-1],dp[i-2]) + cost[i]。
這裡為啥要加上cost[i],,因為題目中說了:每當你爬上一個階梯你都要花費對應的體力值
3.初始化dp數組;
根據上面的遞推公式,要初始化前兩個。
dp[0] = cost[0]
dp[1] = cost[1]
4.确定周遊順序:
由遞推公式可知:
第一個和第二個确定第三個。是以正向周遊。
5.模拟dp看結果:
用示例2,cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]:
相應dp數組:[1, 100, 2, 3, 3, 103, 4, 5, 104, 6]
完整代碼
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
dp = [0] * len(cost)
dp[0] = cost[0]
dp[1] = cost[1]
for i in range(2,len(cost)):
dp[i] = min(dp[i-1],dp[i-2]) + cost[i]
return min(dp[-1],dp[-2])