爬樓梯都還記得吧?
f(x)=f(x-1)+f(x-2)
,斐波那契數列。
本題是爬樓梯的變形題:爬樓梯的最少成本
上題!!
數組的每個下标作為一個階梯,第 i 個階梯對應着一個非負數的體力花費值 cost[i](下标從 0 開始)。
每當爬上一個階梯都要花費對應的體力值,一旦支付了相應的體力值,就可以選擇向上爬一個階梯或者爬兩個階梯。
請找出達到樓層頂部的最低花費。在開始時,你可以選擇從下标為 0 或 1 的元素作為初始階梯。
示例 1:
輸入:cost = [10, 15, 20]
輸出:15
解釋:最低花費是從 cost[1] 開始,然後走兩步即可到階梯頂,一共花費 15 。
示例 2:
輸入:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
輸出:6
解釋:最低花費方式是從 cost[0] 開始,逐個經過那些 1 ,跳過 cost[3] ,一共花費 6 。
- 題目來源:劍指 Offer II 088. 爬樓梯的最少成本
第一反應
這題目讀完有一種将動态規劃 DP(做比較得最大值或最小值)和 爬樓梯斐波那契結合的感覺。
爬樓梯都是從後面往前想,最後一台階 = 前面一台階+1步 或者 前面一台階+2步
台階是 n 階,到達階頂是 n+1
到達第 n 階的最小花費等于(到達第 n-1 階的最小花費和在 n-1 階花費的和)與(到達第 n-2 階的最小花費和在 n-2 階花費的和)二者的最小值。
怎麼了解?因為到達第 n 階的花費是不包括 n 那一階的花費的,隻包含它前面那一階的花費和在這一階之前的最小花費的。前一階,可能是相距 1 步,也可能是相距 2 步。
轉化為代碼即:
less[n] = Math.min(less[n-1]+cost[n-1],less[n-2]+cost[n-2])
對吧,和預測一緻,動态規劃 DP 比較值,以及斐波那契數列的思路結合。
第二反應
斐波那契一般就手動定義初始項就好了,本題的初始階梯,比如數組 [1],[1,1],都是可以分别跨一步、兩步登到階梯頂部,是以不需要花費,花費為 0 ;
即 less[0]=0 、 less[1]=0
剩下的就用一層 for 循環,然後套用上述公式即可。
var minCostClimbingStairs = function(cost) {
let less = []
less[0]=0
less[1]=0
for(let n=2;n<cost.length;n++){
less[n] = Math.min(less[n-1]+cost[n-1],less[n-2]+cost[n-2])
}
return less[cost.length]
}
第三反應
小結:
這題如果不是用動态規劃+斐波那契去解,真的就會很麻煩,要考慮的情況太多了。