參考答案,特別鳴謝:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/scala-dong-tai-gui-hua-di-gui-by-zx233/數組
0. 題目描述ui
數組的每一個索引作爲一個階梯,第 i個階梯對應着一個非負數的體力花費值 cost[i](索引從0開始)。spa
每當你爬上一個階梯你都要花費對應的體力花費值,而後你能夠選擇繼續爬一個階梯或者爬兩個階梯。scala
您須要找到達到樓層頂部的最低花費。在開始時,你能夠選擇從索引爲 0 或 1 的元素做爲初始階梯。code
1. 樣例數據blog
dp | 1 | 1 | 7 | 9 | 10 | 9 |
費用 | 1 | 1 | 6 | 8 | 3 | 0 |
下標 | 0 | 1 | 2 | 3 | 4 | 終點 |
2. 分析最優子結構遞歸
假設咱們如今已經到達了樓頂nums[10],要想獲得最小的消耗,那就須要在到達頂樓前的一步就是最小的消耗,到達樓頂前的一步一共有兩種走法,索引
一個是走一步: 下標4到終點,另外一種是走兩步:下標3到終點leetcode
爲獲得最優解,咱們須要比較這兩個走法的最小值.
咱們設opt(i)爲當前到第i個臺階時的最優解(最小的消耗),到達樓頂時:opt(10) = min{ opt(3) , opt(4) }+nums(5)get
3. 分析邊界
題目已經告訴咱們,第一步能夠選擇第一階或者第二階,因此程序的邊界就是opt(0) = nums(0), opt(1) = nums(1)
4. 遞歸,超時
//1. 遞歸作法,超時 func Min(i,j int)int{ if i < j { return i } return j } func helper(cost []int,count int) int{ if count == 0 || count ==1{ return cost[count] } sum := Min(helper(cost,count-1),helper(cost,count-2)) + cost[count] return sum } func minCostClimbingStairs(cost []int) int { return Min(helper(cost,len(cost)-1),helper(cost,len(cost)-2)) }
5. 動態規劃
/** 1,1,6,8,3,0 下標:0,1,2,3,4,5終點 到達下標 0 ,須要最小花費1 到達下標 1 ,須要最小花費1 到達下標 2 ,須要最小花費Min(1+6,1+6) = 7 到達下標 3 ,須要最小花費MIn(1+8,7+8) = 9 到達下標 4 ,須要最小花費Min(7+3,9+3) = 10 到達下標 5 ,須要最小花費Min(9+0,10+0) = 9 */ func minCostClimbingStairs2(cost []int)int{ if len(cost) == 1{ return cost[0] }else if len(cost) == 2{ return Min(cost[0],cost[1]) } opt1 := cost[0] opt2 := cost[1] i := 2 for i <= len(cost){ if len(cost) == i { return Min(opt1,opt2) }else{ temp := Min(opt1+cost[i],opt2+cost[i]) opt1 = opt2 opt2 = temp } } return opt1 }