PAT A1033 To Fill or Not to Fill
思路:注意根据贪心策略,将加油站根据距离的远近进行排序。由于初始油箱为空,若最初的加油站距离不为 0,则无法到达目的地。
从 0 号加油站开始遍历,遍历能到达且油价最低(除了当前油价)的加油站,设置为目的加油站。
若遍历到第一个小于当前油价的加油站 A,立刻结束遍历,因为可以在当前加油站加到刚好到 A 的油量,到达 A 之后使用的油价格更低。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int MAXN = 505;
const int INF = 1e9;
typedef struct {
double price, dist;
} Station;
Station st[MAXN];
double C_max, D, D_avg;
int N;
bool cmp(Station a, Station b) {
return a.dist < b.dist;
}
int main() {
cin >> C_max >> D >> D_avg >> N;
for(int i = 0; i < N; i++) {
cin >> st[i].price >> st[i].dist;
}
st[N].price = 0;
st[N].dist = D;
sort(st, st + N, cmp);
if(st[0].dist != 0) {
printf("The maximum travel distance = 0.00\n");
return 0;
}
double ans = 0, nowTank = 0, maxDist = C_max * D_avg;
int nowStation = 0;
while(nowStation < N) {
int idx = -1;
double minPrice = INF;
for(int i = nowStation + 1; i <= N &&
st[i].dist - st[nowStation].dist <= maxDist; i++) {
if(st[i].price < minPrice) {
minPrice = st[i].price;
idx = i;
// 现在不加满,加到刚好够更低价的下一站
if(minPrice < st[nowStation].price) {
break;
}
}
}
if(idx == -1) break;
double needTank = (st[idx].dist - st[nowStation].dist) / D_avg;
if(minPrice < st[nowStation].price) {
if(nowTank < needTank) {
ans += (needTank - nowTank) * st[nowStation].price;
nowTank = 0;
} else {
nowTank -= needTank;
}
} else {
ans += (C_max - nowTank) * st[nowStation].price;
nowTank = C_max - needTank;
}
nowStation = idx;
}
if(nowStation == N) {
printf("%.2f\n", ans);
} else {
printf("The maximum travel distance = %.2f\n", st[nowStation].dist + maxDist);
}
return 0;
}