EOJ-1855 Expedition
http://acm.cs.ecnu.edu.cn/problem.php?problemid=1855
题意:一辆车每行驶一单位的路程就消耗一单位的油,给出n个加油站以及他们的位置和可加油量,给出初始油量P和车与目的地的位置L,求需要加油的最少次数。
思路:贪心,先把初始P全部耗尽看能走的路程是否超过L,否则就加一次油。将新路程加上当前途中经过的加油站能加油量的最大值,直到能行驶的路程大于等于L。
因为考虑加油量有重复的情况,这里用了堆,优先队列,每次出队的是队内元素的最大值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }