【问题标题】:Gas Station-like Algorithm with minimum cost? Greedy or DP?最低成本的类似加油站的算法?贪婪还是DP?
【发布时间】:2014-02-17 21:58:57
【问题描述】:

我在高速公路上有一组n 服务站D[],因此D[i]i 站距高速公路起点的距离。

我还有一系列费用C[],其中C[i] 是在i 车站维修我的车辆的费用。

我必须在第一个车站维修我的汽车,而我的汽车在车站之间最多可以行驶 100 英里。

以最低成本从高速公路起点到终点的最有效算法是什么(我需要知道要停在哪些车站)?我能够找到一个贪婪的解决方案来最小化停靠点的数量,但是为了最小的成本,我认为 DP 具有最优子问题:

bestcost[j] = min( 0<i<j bestcost[i] + C[j] s.t. D[j]-D[i] <= 100)

并有一个单独的数组last[j],其中包含要停止的最后一个站点,这将是上述子问题中最好的i

这是正确的方法,还是有更好的 Greedy / DP 解决方案?

【问题讨论】:

  • 我没有看到一个贪婪的解决方案。 DP重复是正确的。您可以使用单调队列获得运行时O(n),该队列允许您在O(1) 中找到最小值,这是最佳的并且具有较低的常数因子。如果您的自行车的续航里程不是恒定的,这甚至也有效。
  • @NiklasB。实际上他的解决方案是贪婪的,在每一站他都会只使用成本来寻找最佳选择..他的解决方案工作正常,除了它不是最优的,因为他没有考虑每个距离存在多少气体,他能有多少重新填写该价格会使这里的问题变得更加复杂,并且使每单位天然气的价格更便宜并不总是停下来的最佳选择
  • @KhaledAKhunaifer 请仔细阅读我的问题,我不考虑存在多少汽油,因为这不是加油站的问题,而是一种变体。这是一个服务站问题,每次我停在给定的车站i时,我都必须支付固定费用C[i]
  • @Anagha as Niklas B. 提到,你可以从终点站倒退,每次经过每个车站,更新从这个车站到达终点站的最低成本。我在这里没有看到任何贪婪。
  • @Khaled:这是一个示例实现,也许这有助于说服您:ideone.com/gm5eit

标签: algorithm dynamic-programming greedy


【解决方案1】:

递归最好写成

bestcost_serviced_at[j] =
  min(0<i<j: bestcost_serviced_at[i] + C[j] s.t. D[j]-D[i] <= 100)

因为假设车辆实际停在车站j 进行服务,循环给出了最优成本。

那么问题的解决方法就是

min (j: bestcost_serviced_at[j] s.t. highway_end - D[j] <= 100)

我认为贪心算法行不通。

【讨论】:

    【解决方案2】:

    我认为你的 DP 有点不完整,这里有一个更全面的 DP 复现:-

    if(highway_end-D[i]>100) {
    
       minCost[i] = min(0<i<j && D[j]-D[i] <= 100 : minCost[j]+C[i])
    } 
    
    else  minCost[i]  = C[i]     
    
    minCost[i] = minimum cost to reach destination if you have filled up at i
    

    根据距起点的距离对站点进行排序,并在较高到较低的站点距离中使用 DP。使用排序数组查找

    编辑: -

    可以使用最小堆在O(NlogN) 中完成。

    【讨论】:

    • 可以在O(n)中实现,但如果距离是预先排序的
    • @NiklasB。即使预先排序了如何在 O(1) 中满足每个子问题的 D[j]-D[i]
    • 分段树每次转换为您提供 O(log n)。正如我所提到的,具有滑动窗口算法的单调队列甚至允许恒定时间转换。稍后我会写一个答案。
    • 如果您有兴趣,请查看我的答案以获取简单的O(n) 算法来解决重复问题
    猜你喜欢
    • 2015-09-18
    • 1970-01-01
    • 2011-07-19
    • 2011-02-10
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多