题意:这道题要求的是最少的加油次数,告诉你n个加油站的距离和每个加油站可以加的油。让你求能不能到达终点,如果可以的话最少需要加多少油。
解法:这可以用优先队列来解决。我们想象,当经过一个加油站时,我们不一定加油,但是我们一定可以加油。因为我们到达了这个加油站,所以相应
的获得了可以加油的权利,但是我们可以不加,当我们足以行驶到下一个加油站时,我们就可以选择不加,但是当我们无法行驶到下一站时,就不需要加。
这给我们一种感觉,我们可以把这种权利用优先队列保存起来,当我们需要加油的时候,就使用我们的权利,为了少加几次油,我们每次都加权利中的最
大的那个油量,如果我们的权利用尽了还是没能行驶到终点,那就说明到达不了。
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
struct stop
{
int x;
int v;
}s[10010];
bool comp(stop s1, stop s2)
{
return s1.x < s2.x;
}
int main()
{
int n, i, L, P;
while(~scanf("%d",&n))
{
for(i = 0; i < n; i++)
scanf("%d%d",&s[i].x, &s[i].v);
scanf("%d%d",&L,&P);
for(i = 0; i < n; i++)
s[i].x = L - s[i].x; //转化为加油站到起点的距离
s[n].x = L;
s[n++].v = 0; //把终点也认为是加油站
sort(s, s+n, comp);
priority_queue<int, vector<int>, less<int> > Q; //值大的优先
int rest = P; //剩余油量
int ans = 0; //加油次数
int pos = 0; //卡车所在的上一个位置
for(i = 0; i < n; i++)
{
int dis = s[i].x - pos; //从上个加油站到此位置要行驶的距离
while(rest - dis < 0) //剩余油量不能到达此位置
{
if(Q.empty()) //没有油可加
{
ans = -1;
break;
}
rest += Q.top();
Q.pop();
ans++;
}
if(ans == -1)
break;
rest = rest - dis;
pos = s[i].x;
Q.push(s[i].v);
}
printf("%d\n",ans);
}
return 0;
}