传送门:http://poj.org/problem?id=2431
【分析】。因为希望加油次数尽可能少,所以当燃料为0了之后再加油是最好的选择。基于贪心的思想,当燃料为0时,选择能加油量最大的加油站。所以可以用一个优先队列来保存经过的加油站的油量,当需要加油时,取出队列中的最大元素即可。
#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int kMaxn = 10000 + 10;
struct aa
{
int d,v;
}a[kMaxn];
bool cmp(aa x, aa y)
{
return x.d < y.d;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; i++)
scanf("%d %d", &a[i].d, &a[i].v);
int l,p;
scanf("%d %d", &l, &p);
for(int i = 1; i <= n; i++)
a[i].d = l - a[i].d; //把这个加油站到起点的距离变成加油站到终点的距离
sort(a + 1, a + 1 + n, cmp); //离终点按从近到远等于离起点从远到近,离起点距离要从大到小
for(int i=1;i<=n;i++)
{
cout<<a[i].d<<" ";
}
n++;
a[n].d = l; //把终点也认为是加油站,方便写程序
priority_queue<int>Q; //优先队列Q
int pos = 0; //起点
bool flag = true;
int sum = 0; //加油站数量
for(int i = 1; i <= n; i++)
{
p = p - (a[i].d - pos); //让剩余的油等于能到下一个加油站。
pos = a[i].d; //起点等于这个加油到终点的距离、
while(p < 0) //不断加油直到油量足够行驶到下一个加油站
{ //剩下的油能够到下一个加油站,则不用加油,直接把这个加油站的油加入到队列
if(Q.empty()) //全加完了都 不足以到终点
{
flag = false;
break;
}
p += Q.top();
Q.pop();
sum++;
}
if(!flag)
break;
Q.push(a[i].v);
}
if(!flag)
printf("-1\n");
else
printf("%d\n", sum);
}
return 0;
}