EOJ-1855 Expedition

http://acm.cs.ecnu.edu.cn/problem.php?problemid=1855

题意:一辆车每行驶一单位的路程就消耗一单位的油,给出n个加油站以及他们的位置和可加油量,给出初始油量P和车与目的地的位置L,求需要加油的最少次数。

思路:贪心,先把初始P全部耗尽看能走的路程是否超过L,否则就加一次油。将新路程加上当前途中经过的加油站能加油量的最大值,直到能行驶的路程大于等于L。

因为考虑加油量有重复的情况,这里用了堆,优先队列,每次出队的是队内元素的最大值。

 1 #include<map>
 2 #include<set>
 3 #include<list>
 4 #include<cmath>
 5 #include<ctime>
 6 #include<queue>
 7 #include<stack>
 8 #include<cctype>
 9 #include<cstdio>
10 #include<string>
11 #include<vector>
12 #include<cstdlib>
13 #include<cstring>
14 #include<iostream>
15 #include<algorithm>
16 using namespace std;
17 struct node{
18     int d,v;
19 }a[10005];
20 bool cmp(node a,node b){
21     return a.d>b.d;
22 }
23 int main(){
24     int n;
25     while(~scanf("%d",&n)){
26         int L,P;
27         for(int i=0;i<n;i++)
28             scanf("%d%d",&a[i].d,&a[i].v);
29         scanf("%d%d",&L,&P);
30         sort(a,a+n,cmp);                    //将其按距离大到小排序(注意是离目的地的距离)
31         int cur=P;                            //当前路程
32         int cnt=0,k=0;                        //cnt为加油站计数,k用来标记最前一个且尚未入队的元素
33         priority_queue<int> Q;
34         while(1){
35             if(cur>=L) break;                //走到了目的地
36             else{
37                 for(int i=k;i<n;i++){
38                     if(L-a[i].d<=cur) Q.push(a[i].v);    //将途中经过的加油站入队
39                     else {k=i;break;}                    //标记当前位置,让入队元素不重复(只能加一次油)
40                 }
41                 if(Q.empty()){cnt=-1;break;}            //如果队伍为空,则没有加油站可以继续提供,则不能到达
42                 cur+=Q.top();                            //当前位置加上油量最大值
43                 Q.pop();                                //删除该元素
44                 cnt++;
45             }
46         }
47         printf("%d\n",cnt);
48     }
49     return 0;
50 }
View Code

 

 

posted on 2013-07-08 00:49  KimKyeYu  阅读(384)  评论(0编辑  收藏  举报

导航