就像《挑战程序设计竞赛》所说的——在到达加油站之前时,就获得一次在之后加油的权利。简单的说就是,当你经过第 i 个加油站时,先别加油,先压入优先队列,当你到达第 k 个加油站时,计算你车里的油够不够,若不够则从优先队列中选取一个在前面几站中最大的加油站,若还不够,加第二大的加油站.....
总的来说,先考虑能不能到下一站,能,则不加油;不能,就加前面几站中最大的。
这道题目:
1.给你加油站的距离是到终点的距离,而非是到卡车的距离。
2.给你的加油站的距离是随机的,而非排过序的,即在我看来必须有对加油站排序一次(当然可能是我太弱鸡的,还有其他方法^-^,有的话请告诉我,希望您不吝赐教)
3.优先队列的使用,默认是从大到小输出
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 10000 + 10;
int the_num;
struct Node {
int pos, fule;
};
Node stop[maxn];
int the_dis, have_fuel;
void solve() {
priority_queue<int> que;
int count = 0, current_position = 0;
for (int i = 0; i <= the_num; i++) {
int need_dis =stop[i].pos - current_position;
while (need_dis > have_fuel) {
if (que.empty()) {
puts("-1");return;
}
have_fuel += que.top();
que.pop();
count++;
}
have_fuel -= need_dis;
current_position =stop[i].pos;
que.push(stop[i].fule);
}
printf("%d\n", count);
}
bool cmp(const Node& a, const Node& b) {
return a.pos < b.pos;
}
int main() {
while (scanf("%d", &the_num) == 1) {
for (int i = the_num - 1; i >= 0; i--) {
scanf("%d%d", &stop[i].pos, &stop[i].fule);
}
scanf("%d%d", &the_dis, &have_fuel);
//题意是距离终点的距离而非是离开车的距离,具体可看Poj—2431的Hint
for (int i = 0; i < the_num; i++) {
stop[i].pos=the_dis-stop[i].pos;
}
//把终点当做一个加油站
stop[the_num].pos = the_dis;
stop[the_num].fule= 0;
//对所有的站点排序
sort(stop, stop + the_num + 1, cmp);
solve();
}
return 0;
}
如果先要快速掌握优先队列的STL的使用方法转:http://blog.csdn.net/notcoldheike/article/details/76915753
谢谢观看(^-^)!!!