问题链接:POJ2431 Expedition
【问题描述】
一群奶牛抢了一辆卡车决定前往树林里探险。但是由于他们的驾驶技术太糟,油箱在路上弄破了,所以他们每前进一个单位的路程就会漏掉一个单位的油。为了修好油箱,奶牛们必须前往最近的城市(不会超过1000000单位路程)。在当前位置和城市之间有N个加油站,奶牛可以在加油站加1到100单位的油。
对于人来说,树林是危险的地方,对奶牛来说,更是这样,所以奶牛门尽可能的少停站加油,幸运的是,这辆卡车的油箱非常大,你可以认为它的容量是无限大的。卡车在离城市P单位时还有L个单位的油。
你要计算出奶牛们至少要停几站才能到城市,或者奶牛们根本到不了城市。
【输入格式】
第一行一个整数N,接下来的N行,每行包含两个用空格隔开的整数,分别表示该加油站离城市的距离和最多可以加多少油。最后一行包含的两个整数为P和L。
【输出格式】
如果卡车能到达城市,输出最少要停的次数,否则输出-1。
【输入样例】
4
4 4
5 2
11 5
15 10
25 10
【输出样例】
2
【样例解释】
现在卡车离城市25个单位,卡车离有10个单位的油。在路上,有4个加油站,分别距离城市4,5,11,15,分别距离卡车则为21,20,14,10。这些加油站分别最多可加油4,2,5,10个单位。
开10个单位,加满10单位油,再开4个单位,加满5单位油,接着直接开到城市。
【数据范围】
0<N<=10 000 , 0<P<=1 000 000
【来源】
poj 2431
问题分析:本题的主要算法是贪心算法,贪心策略为每次在卡车能经过的加油站中,选择所加油量最大的加油站加油,直到卡车能到达城市。
我们可以先将每个加油站按离城市的距离由大到小排序,即先找出距离车最近的加油站,假设卡车将油耗尽所到的离城市的距离为R,依次比较加油站到城市的距离是否大于或等于R,如果是,则满足条件,在满足条件的加油站中选择所加油量最大的(这里可以使用优先队列存放油的数量),然后重复上述操作。
注意:要判断无解情况,在找当前卡车能开到的加油站时,如果优先队列为空,并且第一个所比较的加油站到城市的距离小于R,则说明卡车不能到达城市,需输出-1。
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
int fuel;//加油站的燃油数量
int dist;//加油站与城市的距离
friend bool operator<(node x,node y)
{
return x.dist>y.dist;
//加油站距离城市从大到小排序即距离车从近到远排序
}
}a[10005];
int n,l,p;
int main()
{
while(scanf("%d", &n) != EOF)
{
priority_queue<int> q;//燃油从大到小排序
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].dist,&a[i].fuel);
}
sort(a,a+n);
scanf("%d%d", &l, &p);
q.push(p);
int s=0;
int i=0;
while(l>0&&!q.empty())
{
s++;
l-=q.top();
q.pop();
while(i<n&&l<=a[i].dist)
{
q.push(a[i].fuel);
i++;
}
}
if(l<=0)
{
cout<<s-1<<endl;
}
else
{
cout<<-1<<endl;
}
}
return 0;
}