Leetcode_Dynamic_Programming -- 746. Min Cost Climbing Stairs [easy]

On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed).

Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1.

在爬台阶的情况下,我们有个非负的数组cost,cost [ i ]表示第 i 步需要付出的代价

如果你愿意付出代价,你可以走一步或者两步,你需要找到到达台阶顶端的最小代价,同时你可以从台阶起始第一个台阶开始或者从第二个台阶开始走

Example 1

Input: cost = [10, 15, 20]
Output: 15
Explanation: Cheapest is start on cost[1], pay that cost and go to the top.

Example 2:

Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
Output: 6
Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3].

Note:

  1. cost will have a length in the range [2, 1000].
  2. Every cost[i] will be an integer in the range [0, 999].

这里利用动态规划有两种方法,分别是从两个不同角度去思考得到的。

第一种思路考虑到达最顶端的台阶时,没有考虑最后登顶的那个台阶,例如cost = [10,15,20],要到最顶端的台阶,要么是从cost=15的台阶上跨上去,要么是从cost=20的台阶上跨上去,min_cost 表示跨上第 i 个台阶前需要的最小代价,因此其动态方程是:min_cost [ i ] = min( min_cost [ i-1 ]+cost[i-1] , min_cost [ i-2 ]+cost[i-2]),由于没有考虑最后登上的那个台阶,所以需要选取在 i-1 和 i-2 台阶上花费最小的台阶。

min_cost [ 0 ] = cost [ 0 ]

min_cost [ 1 ] = cost [ 1 ]

n >2 时,min_cost [ i ] = min( min_cost [ i-1 ]+cost[i-1] , min_cost [ i-2 ]+cost[i-2])

第二种思路是要到达最顶端的台阶,那么必须踩在那个台阶上,还是cost = [10,15,20]的例子,如果要到达最顶端的台阶,其实是踩在len(cost)+1台阶,则状态转移方程是:min_cost [ i ] = cost [ i ] + min(min_cost [ i-1 ] , min_cost [ i-2 ]),另外由于强调必须踩在len(cost)+1台阶上,所以min_cost的长度必须是len(cost)+1

min_cost [ 0 ] = 0

min_cost [ 1 ] = 0

n >2 时,min_cost [ i ] = cost [ i ] + min(min_cost [ i-1 ] , min_cost [ i-2 ])

注意上述两种思路的区别

Solutions:

Python

(1)方法1强调到达顶端,但是脚步没有落在那个台阶上

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        length = len(cost)+1
        min_cost = [0 for i in range(length)]
        for i in range(2,length):
            min_cost[i] = min(cost[i-1]+min_cost[i-1],cost[i-2]+min_cost[i-2])
        return min_cost[-1]

(2)方法2强调脚步最终落在最后的台阶上,那么min_cost就应该是此台阶的cost加上其前一个或者前两个台阶cost中较小的那个,

class Solution:
    '''
    由题目可得,脚步可以停在cost的最后一个数或者倒数第二个数上
    我们也可以理解为cost有n个数,那么到达n+1个台阶上时,花费的最小代价是多少?
    与前一篇climb stairs题目差不多,状态转移方程可以写为:
    min_cost[i] = cost[i]+min(min_cost[i-1],min_cost[i-2])
    min_cost长度为cost长度n,其存储的是到达n+1个台阶时,需要花费的最小代价
    '''
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        min_cost = [0 for i in range(len(cost))]
        min_cost[0] = cost[0]
        min_cost[1] = cost[1]
        length = len(cost)
        for i in range(2,length):
            min_cost[i] = cost[i] + min(min_cost[i-1],min_cost[i-2])
        return min(min_cost[-1],min_cost[-2])

(3)方法3将方法1的空间复杂度缩减为常数
class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        length = len(cost)+1
        a = 0
        b = 0
        for i in cost:
            min_cost = i + min(a,b)
            a = b
            b = min_cost
            
        return min(a,b)

 

Reference:

https://www.cnblogs.com/grandyang/p/8343874.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值