871. Minimum Number of Refueling Stops

解法

还是不到家,两个思路都想到了但是一个浪费空间一个没想透彻= =

解法一:DP

肯定不能把油量作为dp的下标,所以我们考虑dp[i][j],表示到达车站i,加了j次油时剩余的最大油量。注意,我们考虑的是在车站i-1加不加油。
令车站i和车站i-1之间的距离为dis

  • 假如不加油,那么到达车站i时候的最大油量为:dp[i-1][j]-dis
  • 假如加油,那么到达车站i时候的最大油量为:max(-1, dp[i-1][j-1]+Fuel[i-1]-dis),注意只有dp[i-1][j-1]非负时可以这么算。
    否则由于i-1车站只加j-1次油是到不了的,所以不可能在车站i-1再加油

状态转移方程为:
d p [ i ] [ j ] = { max ⁡ ( − 1 , d p [ i − 1 ] [ j ] − d i s , d p [ i − 1 ] [ j − 1 ] + F u e l [ i − 1 ] − d i s ) , j &gt; 0  and  d p [ i − 1 ] [ j − 1 ] ≥ 0 max ⁡ ( − 1 , d p [ i − 1 ] [ j ] − d i s ) , j = = 0  or  d p [ i − 1 ] [ j − 1 ] &lt; 0 dp[i][j] = \left\{\begin{matrix} \max(-1, dp[i-1][j]-dis, dp[i-1][j-1]+Fuel[i-1]-dis) &amp; , j&gt;0\text{ and }dp[i-1][j-1]\ge 0\\ \max(-1, dp[i-1][j]-dis) &amp; , j==0\text{ or }dp[i-1][j-1]&lt; 0\\ \end{matrix}\right. dp[i][j]={max(1,dp[i1][j]dis,dp[i1][j1]+Fuel[i1]dis)max(1,dp[i1][j]dis),j>0 and dp[i1][j1]0,j==0 or dp[i1][j1]<0

观察一下状态转移方程,跟背包问题一样,是可以空间优化,从而把i这一维给去掉的。

最后只要找到最小的j,使得dp[j]非负就行了

class Solution(object):
    def minRefuelStops(self, target, startFuel, stations):
        """
        :type target: int
        :type startFuel: int
        :type stations: List[List[int]]
        :rtype: int
        """
        stations.append([target,0])
        n = len(stations)
        dp = [-1]*(n+1)
        dp[0] = startFuel-stations[0][0] if startFuel>=stations[0][0] else -1
        for i in xrange(1, n):
            for j in xrange(i+1, -1, -1):
                dis = stations[i][0]-stations[i-1][0]
                dp[j] = dp[j]-dis
                if j>0 and dp[j-1]>=0:
                    dp[j] = max(dp[j-1]+stations[i-1][1]-dis, dp[j])
                dp[j] = max(-1, dp[j])
        l = 0
        r = n-1
        while r>l:
            mid = (r+l)>>1
            if dp[mid]>=0:
                r = mid
            else:
                l = mid+1
        return r if dp[r]>=0 else -1

解法二:堆

一开始我想过贪心法,就是先能走多远走多远,缺油了就找经过的最大的车站加油然后再走。不过当时脑子傻了,最大的加完也走不到会出错,然后就转投了DP的怀抱= =
其实可以一直加,加到能走到下一个站点为止,用最大堆就可以了

class Solution(object):
    def minRefuelStops(self, target, startFuel, stations):
        """
        :type target: int
        :type startFuel: int
        :type stations: List[List[int]]
        :rtype: int
        """
        stations.append([target,0])
        n = len(stations)
        ans = 0
        from heapq import heappush, heappop
        pq = []
        for place, fuel in stations:
            while startFuel<place and len(pq):
                startFuel -= heappop(pq)
                ans += 1
            if startFuel<place:
                return -1
            heappush(pq, -fuel)
        return ans

卧槽,快了一个数量级……

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值