- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在研究这个问题,我认为这是加油站问题的一个变体。结果,我使用贪心算法来解决这个问题。我想请问有没有人帮我指出我的算法是否正确,谢谢。
我的算法
var x = input.distance, cost = input.cost, c = input.travelDistance, price = [Number.POSITIVE_INFINITY];
var result = [];
var lastFill = 0, tempMinIndex = 0, totalCost = 0;
for(var i=1; i<x.length; i++) {
var d = x[i] - x[lastFill];
if(d > c){ //car can not travel to this shop, has to decide which shop to refill in the previous possible shops
result.push(tempMinIndex);
lastFill = tempMinIndex;
totalCost += price[tempMinIndex];
tempMinIndex = i;
}
//calculate price
price[i] = d/c * cost[i];
if(price[i] <= price[tempMinIndex])
tempMinIndex = i;
}
//add last station to the list and the total cost
if(lastFill != x.length - 1){
result.push(x.length - 1);
totalCost += price[price.length-1];
}
您可以在此链接试用该算法 https://drive.google.com/file/d/0B4sd8MQwTpVnMXdCRU0xZFlVRlk/view?usp=sharing
最佳答案
首先,关于您的解决方案。
即使是最简单的输入也有一个错误。当您决定距离变得太远并且您应该在之前的某个时间点完成时,您不会更新距离并且加油站会向您收取更多费用。修复很简单:
if(d > c){
//car can not travel to this shop, has to decide which shop to refill
//in the previous possible shops
result.push(tempMinIndex);
lastFill = tempMinIndex;
totalCost += price[tempMinIndex];
tempMinIndex = i;
// Fix: update distance
var d = x[i] - x[lastFill];
}
即使进行了此修复,您的算法在某些输入数据上仍会失败,如下所示:
0 10 20 30
0 20 30 50
30
它应该在每一种汽油上加满以最小化成本,但它只是加满最后一种。
经过一番研究,我想出了解决方案。我将尝试尽可能简单地解释它,使其独立于语言。
对于每个 G
加油站,我们将计算最便宜的加油方式。我们将递归地这样做:对于每个加油站,让我们找到我们可以到达 G
的所有加油站 i
。对于每个 i
,计算可能的最便宜的加注量,并在给定剩余汽油的情况下加注 G
的加注成本。启动加油站的成本为 0。更正式地说:
CostOfFilling(x)
、Capacity
和 Position(x)
可以从输入数据中检索。
所以,问题的答案很简单BestCost(LastGasStation)
现在,javascript 中的解决方案让事情变得更清晰。
function calculate(input)
{
// Array for keeping calculated values of cheapest filling at each station
best = [];
var x = input.distance;
var cost = input.cost;
var capacity = input.travelDistance;
// Array initialization
best.push(0);
for (var i = 0; i < x.length - 1; i++)
{
best.push(-1);
}
var answer = findBest(x, cost, capacity, x.length - 1);
return answer;
}
// Implementation of BestCost function
var findBest = function(distances, costs, capacity, distanceIndex)
{
// Return value if it's already have been calculated
if (best[distanceIndex] != -1)
{
return best[distanceIndex];
}
// Find cheapest way to fill by iterating on every available gas station
var minDistanceIndex = findMinDistance(capacity, distances, distanceIndex);
var answer = findBest(distances, costs, capacity, minDistanceIndex) +
calculateCost(distances, costs, capacity, minDistanceIndex, distanceIndex);
for (var i = minDistanceIndex + 1; i < distanceIndex; i++)
{
var newAnswer = findBest(distances, costs, capacity, i) +
calculateCost(distances, costs, capacity, i, distanceIndex);
if (newAnswer < answer)
{
answer = newAnswer;
}
}
// Save best result
best[distanceIndex] = answer;
return answer;
}
// Implementation of MinGasStation function
function findMinDistance(capacity, distances, distanceIndex)
{
for (var i = 0; i < distances.length; i++)
{
if (distances[distanceIndex] - distances[i] <= capacity)
{
return i;
}
}
}
// Implementation of Cost function
function calculateCost(distances, costs, capacity, a, b)
{
var distance = distances[b] - distances[a];
return costs[b] * (distance / capacity);
}
带有代码的完整可用 html 页面可用 here
关于algorithm - 加油站变体算法验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33820316/
1.题目 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i + 1 个加油站需要消耗汽油 cost[i] 升。你
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我是一名优秀的程序员,十分优秀!