POJ2431 探險 解題報告

【問題描述】  
  
  一羣奶牛搶了一輛卡車決定前往樹林裏探險。但是由於他們的駕駛技術太糟,油箱在路上弄破了,所以他們每前進一個單位的路程就會漏掉一個單位的油。爲了修好油箱,奶牛們必須前往最近的城市(不會超過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<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=10005;
int N,P,L;
struct data
{
	int x,w;
};
data a[maxn];
bool cmp1(data aa,data bb)  //按加油站離城市的距離由大到小排序
{
	return aa.x>bb.x;
}
struct cmp2
{
	bool operator()(data aa,data bb)
	{
		return aa.w<bb.w;
	}
};
void solve()
{
	priority_queue<data,vector<data>,cmp2>q; //按加油站所加的最大油量定義優先隊列
	int i=1,ok=1,cnt=0;
	while(P>0 && i<=N)
	{
		P=P-L;  //假設卡車當前把所剩的油用盡,所到達的離城市最近的距離
		L=0;  
		if(P<=0)  break;  //卡車所剩的汽油能使它到達城市
		if(q.empty() && a[i].x<P)  //卡車所剩的油不能支持它到達離自己最近的加油站加油,即不能到達城市
		{
			ok=0;
			break;
		}
		while(i<=N && a[i].x>=P)  //當前卡車能到達的加油站
		{
			q.push(a[i]);
			i++;
		}
		if(!q.empty())
		{
			data t=q.top();  q.pop();
			L+=t.w;
			cnt++;
		}
	}
	if(ok==0)  printf("-1\n");
	else  printf("%d\n",cnt);
}
int main()
{
	freopen("48.in","r",stdin);
	//freopen("48.out","w",stdout);
	scanf("%d",&N);
	for(int i=1;i<=N;i++)
	scanf("%d%d",&a[i].x,&a[i].w);
	scanf("%d%d",&P,&L);
	sort(a+1,a+1+N,cmp1);
	solve();
	return 0;
}


發佈了57 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章