- 参考自@max_xbw 。图画的很好,分析很详细,“对于贪心的题目,测试样例,必须自己去体会一遍”,赞。
- 从当前所处的加油站开始,分析要加多少油,接下来要去到哪一个加油站。如果第一个加油站不在起点0那里,那么油箱为空,哪也去不了。
- 在加满油的情况下,能跑到的所有加油站里,如果有一个油价比当前加油站更低的加油站A,那么在当前加油站只需要加到足够去往加油站A的油。需要注意的是,如果有加油站B也在可达范围之内且B的油价比A的油价更低,但B要比A更远些,那么仍是加够去A的油,否则AB这段路上消耗的油就贵了。
- 如果在加满油的情况下,能跑到的所有加油站里,没有油价更偏宜的加油站了。那就先检查,当前加油站加满油是否能到达目的地,能的话,就不用考虑后面的加油站了,不能的话,先把油在这儿加满,去到下一个相对最便宜的加油站。
- 如果在加满油的情况下,能跑到的最远距离内,一个加油站都没有,那么检查是否能到目的地,输出结果。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct NODE {
double price;
double distance;
};
int main() {
double C, D, d;
int N;
cin >> C >> D >> d >> N;
vector<NODE> A;
for (int i = 0; i < N; ++i) {
NODE node;
cin >> node.price >> node.distance;
A.push_back(node);
}
sort(A.begin(), A.end(), [](const NODE& a, const NODE& b) { return a.distance < b.distance; });
if (!(D > 0.0)) {
cout << "0.00" << endl;
} if (A[0].distance > 0.0) {
cout << "The maximum travel distance = 0.00" << endl;
} else {
int i = 0;
double curCapa = 0.0;
double total = 0.0;
while (true) {
bool hasCheaper = false;
int cheaper;
bool hasStation = false;
int station;
for (int j = i + 1; j < (int)A.size() && A[j].distance <= A[i].distance + C * d; ++j) {
if (!hasStation) {
hasStation = true;
station = j;
} else if (A[j].price < A[station].price) {
station = j;
}
if (A[j].price <= A[i].price) {
hasCheaper = true;
cheaper = j;
break;
}
}
if (!hasStation) break;
if (hasCheaper) {
total += ((A[cheaper].distance - A[i].distance) / d - curCapa) * A[i].price;
curCapa = 0.0;
i = cheaper;
} else {
if (D <= A[i].distance + C * d) break;
total += (C - curCapa) * A[i].price;
curCapa = C - (A[station].distance - A[i].distance) / d;
i = station;
}
}
if (D <= A[i].distance + C * d) {
printf("%.2lf", total + ((D - A[i].distance) / d - curCapa) * A[i].price);
} else {
printf("The maximum travel distance = %.2lf", A[i].distance + C * d);
}
}
return 0;
}