(POJ 2431)The truck is 25 units away from the town; the truck has 10 units of fuel. Along the road, there are 4 fuel stops at distances 4, 5, 11, and 15 from the town (so these are initially at distances 21, 20, 14, and 10 from the truck). These fuel stops can supply up to 4, 2, 5, and 10 units of fuel, respectively.
GOAl: A single integer giving the minimum number of fuel stops necessary to reach the town. If it is not possible to reach the town, output -1.
INPUT: 4 (代表4 fuel stops)
15 10 (第一个数字代表该加油站距离town的距离, 第二个数字代表该加油站能够加的油, 下面三行同此)
11 5
5 2
4 4
25 10 (第一个表示路线总的长度为25, 第二个是卡车在起点处具有的油量)
OUTPUT:
2
刚开始, 卡车由P单位的汽油。 卡车没开1单位的距离需要耗掉1单位的汽油。 目的是求出最少要在几个加油站停下来加油, 才能到达L处的目的地
分析: 该题的解决用到了优先队列的知识。 由于所有的加油站都在一条直线上, 所以总会经过每个加油站, 只要看需不需要停下来加油。 所以我们尽可能的往前走, 把中途经过的加油站的能够加的油量放在一个priority queue里面, 然后直到中途没有油了, 我们就决定从priority queue中最大的油量加到tank, 因为既然要加油, 就加到最大的油。 这隐含的意思就是我们会在这一站停下来加油。
程序:
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct fuel_stop{
int pos;
int amount;
}stop[10010];
bool cmp(fuel_stop a, fuel_stop b)
{
return a.pos > b.pos;
}
int main()
{
int N, L, P;
while (scanf("%d", &N) != EOF) {
for (int i = 0; i < N; ++i)
scanf("%d %d", &stop[i].pos, &stop[i].amount);
scanf("%d %d", &L, &P);
sort(stop, stop + N, cmp);
stop[N] = {0,0}; // 终点也是一个stop
priority_queue<int> PQ; // PQ存放经过的每一个stop的油量
int dis = L - stop[0].pos; // 起点距离第一站
int sum_dis = dis; // 总共走了多远
P -= dis;
int i = 0;
int ans = 0;
bool OK = 1;
while (sum_dis < L && OK) {
while (P >= 0) { //當身上油還>=0時繼續前進
dis = stop[i].pos - stop[i+1].pos;
P -= dis;
sum_dis += dis;
PQ.push(stop[i].amount);
++i;
if (i == N) break;
}
while (P < 0 && OK) { // PQ裡面從最多油量開始挑,加入油箱
if (PQ.empty()) OK = 0;
else{
P += PQ.top();
PQ.pop();
++ans; // 加一次油
}
}
}
if (OK) printf("%d\n", ans);
else puts("-1");
}
}
运行结果如下: