题目链接:http://poj.org/problem?id=2431
思路:先把各个加油站离目的地的距离转换为离起点的距离并按距离小到大排序,然后看当前的油量最多能走到哪一个加油站,那么就把它此时能够到达的加油站都加入到队列中,然后在他不能到达的那个加油站取前面油量最大的加油站中的油加油,直道能够到达这个加油站为止。
//2014-7-6
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct Node
{
friend bool operator<(Node n1,Node n2) //按油量的多少,从大到小排序
{
return n1.p<n2.p;
}
int l,p;
};
bool cmp(Node n1,Node n2) //对加油站按离起点的顺序进行排序
{
return n1.l<n2.l;
}
Node node[1000010];
int main()
{
int n,i;
int L,P;
while(~scanf("%d",&n))
{
priority_queue<Node> Q;
int sum=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&node[i].l,&node[i].p);
}
scanf("%d%d",&L,&P);
for(i=0;i<n;i++)
{
node[i].l=L-node[i].l; //转换为离起点的距离
}
sort(node,node+n,cmp); //按离起点的距离进行排序
for(i=0;i<n;i++)
{
if(P>=L) break; //如果现在的油量足够到达目的地,则不用再继续加油啦
if(P>=node[i].l) //经过的加油站,加入到队列中
{
Q.push(node[i]);
}
else
{
while(P<node[i].l && !Q.empty()) //在以前经过的的加油站中,选择油量最多的加油站加油,直到可以到达现在这一个加油站,或是直到所有加油站用完为止
{
Node r=Q.top();
Q.pop();
P=P+r.p;
sum++; //记录所用加油站的个数
}
if(P<node[i].l&& Q.empty())
{
break;
}
Q.push(node[i]); //把这一个加油站加入到队列中
}
}
if(P<L) //为什么会有这一步,因为最后一个加油站只入啦队列,可能没在那儿加油,所有需要这一步,可以看下面这组测试数据
{
while(P<L&&!Q.empty()) //在以前经过的的加油站中,选择油量最多的加油站加油,直到可以到达现在这一个加油站,或是直到所有加油站用完为止
{
Node r=Q.top();
Q.pop();
P=P+r.p;
sum++; //记录所用加油站的个数
}
if(P<L) printf("-1\n");
else printf("%d\n",sum);
}
else printf("%d\n",sum);
}
return 0;
}
/*
5
36 7
34 9
25 3
20 7
10 13
40 10
*/
//输出答案为 4