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; }