POJ 2431 Expedition (贪心 + 优先队列)

题意:一辆卡车要行驶L单位距离,卡车上有P单位的汽油。一共有N个加油站,分别给出加油站距终点距离,及加油站可以加的油量。问卡车能否到达终点?若不能输出-1,否则求出最少加油次数。
解题思路:可以认为"在到达加油站时,获得一次可以在任何时候使用这个加油站加油的资格",而在之后需要加油时,就认为是在之前经过的加油站加的油就可以了。因为希望加油次数最少,所以在燃料不够行驶时选择加油量最大的加油站加油。为了高效性,我们可以使用从大到小的顺序依次取出数值的优先队列。
 1 #include<iostream>
 2 #include<queue> 
 3 #include<algorithm> 
 4 using namespace std;
 5 struct node{
 6     int dis;
 7     int gas;
 8 }a[10005];
 9 
10 bool cmp(node a,node b){
11     return a.dis<b.dis;
12 }
13 int main(){
14     int n;
15     while(cin>>n){
16         for(int i=1;i<=n;i++){
17             cin>>a[i].dis>>a[i].gas; 
18         }
19         int l,p; 
20         cin>>l>>p;
21         //终点 
22         a[n+1].dis=l;
23         a[n+1].gas=0;
24         //将加油站到终点距离变为离起点距离并从小到大排好 
25         for(int i=1;i<=n;i++){
26             a[i].dis=l-a[i].dis;
27         }
28         sort(a+1,a+n+2,cmp);
29         //优先队列,从大到小
30         priority_queue<int>q; 
31         //ans:加油次数,pos:当前位置,tank:剩余油量 
32         int ans=0,pos=0,tank=p;
33         for(int i=1;i<=n+1;i++){
34             //当前位置离下一个加油站的距离 
35             int x=a[i].dis-pos;
36             while(tank<x){
37                 if(q.empty()){
38                     cout<<"-1"<<endl;
39                     return 0;
40                 }
41                 tank+=q.top();
42                 q.pop();
43                 ans++;
44             }
45             tank-=x;
46             pos=a[i].dis;
47             q.push(a[i].gas);    
48         }
49         cout<<ans<<endl;
50     }
51     return 0;    
52 }
原文地址:https://www.cnblogs.com/fu3638/p/6968993.html