题目
题解
贪心。
1. 将终点视为单位油价为0,离起点距离为d的加油站,然后将所有加油站按离起点的距离从小到大排序。排序后,如果如果离起点最近的加油站距离不是0,则汽车无法出发,直接输出结果。
2. 选择下一个车站的策略:
判断是否存在可达的加油站,即将油箱加满能够到达其他加油站?
(1)若存在,则判断是否存在比当前加油站油价便宜的加油站?
① 若存在,则我们选择一个最近的且比当前加油站油价便宜的加油站作为目的地,将油箱加至刚好能到目的地,驱车前往;
② 若不存在,则将油箱加满,驱车前往能到达的加油站中油价最便宜的加油站;
(2)若不存在,则说明无法到达终点
代码
#include<bits/stdc++.h>
using namespace std;
#define pos first
#define price second
#define PDD pair<double, double>
const int N = 1e5+10;
double V, dist, com;
int n;
PDD sta[N];
int main()
{
cin >> V >> dist >> com >> n;
for (int i = 0;i < n;i ++) {
double x, y;
cin >> x >> y;
sta[i] = {y, x};
}
sta[n] = {dist, 0.0};
sort (sta, sta+n);
if (sta[0].pos != 0) return printf ("The maximum travel distance = 0.00\n"), 0;
int i = 0;
double Vdist = V * com;
double cost = 0, cur_V = 0;
while (i < n) { // !!不能枚举终点
int j = i+1, t = -1;
while (j <= n && sta[j].pos <= sta[i].pos + Vdist) {
if (t == -1 || sta[j].price <= sta[t].price) t = j;
if (sta[t].price <= sta[i].price) break;
j ++;
}
if (t == -1) return printf ("The maximum travel distance = %.2lf\n", sta[i].pos + Vdist), 0;
if (sta[t].price <= sta[i].price) { // 正好
if (sta[t].pos <= sta[i].pos + cur_V * com) { // 当前油箱中的油足够
cost += 0;
cur_V -= (sta[t].pos - sta[i].pos) / com;
} else { // 不够,缺的量要补上
cost += ((sta[t].pos - sta[i].pos) / com - cur_V) * sta[i].price;
cur_V = 0;
}
} else { // 加满
cost += (V - cur_V) * sta[i].price;
cur_V = V - (sta[t].pos - sta[i].pos) / com;
}
i = t;
}
printf ("%.2lf\n", cost);
return 0;
}