POJ2431 Expedition【贪心+优先队列】

问题链接: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值