poj2431:Expedition
《挑战程序设计竞赛》
一条路上设置n个加油站,每个加油站能够提供ki个单位的油。一辆车以初始油量P从起点出发,求其到达终点停下加油的最小次数,若不能到达终点,则输出-1
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
struct Stop{ //加油站结构体
int dist; //距离终点的距离
int fuel; //该加油站能够提供的油量
Stop(int d, int f): dist(d), fuel(f) {}
};
vector<Stop> stops; //存储加油站的信息
/*优先级队列(大根堆)存储
* 经过一个加油站,就将该加油站所能提供的油量加入优先级队列
* 当没油时,选择堆顶油量(当前队列中最大油量)进行加油*/
priority_queue<int> q;
int cmp(Stop a, Stop b){
return a.dist > b.dist;
}
int main(){
int n, L, P;
int dist, fuel;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d%d", &dist, &fuel);
stops.push_back(Stop(dist, fuel));
}
scanf("%d%d", &L, &P);
//加油站按照距离重点的距离由远及近排序(即距离源点的距离由近到远)
sort(stops.begin(), stops.end(), cmp);
//为方便处理经过最后一个加油站后,能否到达终点,将终点也视为一个加油站
stops.push_back(Stop(0, 0));
int current = 0; //当前所到位置
int answer = 0; //加油次数
int d; //到下一个加油站的距离
for (int i = 0; i <= n; ++i) {
d = L - stops[i].dist - current; //注意stops[i].dist为从加油站到终点的距离,
//剩余油量不能到达下一个加油站,一直加油,直到能到达下一个加油站
while(d > P) {
if (q.empty()) {
printf("-1\n");
return 0;
}
P += q.top();
q.pop();
++answer;
}
//到达下一个加油站
q.push(stops[i].fuel);
P -= d;
current = L - stops[i].dist;
}
printf("%d\n", answer);
return 0;
}