746使用最小花费爬楼梯

参考答案,特别鸣谢:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/scala-dong-tai-gui-hua-di-gui-by-zx233/

0.  题目描述

数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost[i](索引从0开始)。

每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。

您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。

1.  样例数据

dp 1 1 7 9 10 9
费用 1 1 6 8 3 0
下标 0  1 2 3 4 终点

2.  分析最优子结构

假设我们现在已经到达了楼顶nums[10],要想得到最小的消耗,那就需要在到达顶楼前的一步就是最小的消耗,到达楼顶前的一步一共有两种走法,

  一个是走一步: 下标4到终点,另一种是走两步:下标3到终点

为得到最优解,我们需要比较这两个走法的最小值.
我们设opt(i)为当前到第i个台阶时的最优解(最小的消耗),到达楼顶时:opt(10) = min{ opt(3) , opt(4) }+nums(5)

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

}
原文地址:https://www.cnblogs.com/da-peng/p/11624083.html