poj2431 Expedition (优先队列)

问题描述(机翻)

一群牛抓住一辆卡车,冒险深入丛林探险。由于这些牛的驾驶技术很差,不幸的是,它们撞上了一块岩石,并刺穿了卡车的油箱。现在卡车每行驶一段距离就会泄漏一单位燃料。
为了修理卡车,奶牛需要沿着一条蜿蜒的长路开到最近的城镇(不超过100万个单位的距离)。在这条道路上,在城镇和卡车的当前位置之间,有N个(1 <= N <= 10,000)个燃料站,奶牛可以在那里停下来获取额外的燃料(1…100)。
丛林对人类来说是一个危险的地方,对牛来说尤其危险。因此,奶牛想要在进城的路上尽可能少地停下来加油。幸运的是,他们卡车上的油箱容量是如此之大,以至于它所能容纳的燃料量实际上是没有限制的。卡车目前距离城镇L个单位,有P个单位的燃料(1 <= P <= 1,000,000)。
确定到达城镇所需的最低停站数,或者如果奶牛根本无法到达城镇。

输入

*第1行:单个整数N
*线2 . .N+1:每一行包含两个空格分隔的整数,描述一个燃料站:第一个整数是城镇到加油站的距离;第二个是该站点的可用燃料量。
*第N+2行:两个空格分隔的整数,L和P

输出

*第1行:一个整数,给出到达城镇所需的最低燃油站数。如果无法到达城镇,输出-1。

Sample Input

4
4 4
5 2
11 5
15 10
25 10

Sample Output

2

分析:

显然油量就是能够行驶的距离
且要到达城镇必须经过所有加油站
车辆可以从所有经过的加油站中任意挑选取油
将能够经过的加油站的油量加入优先队列
当油量无法到达下一个加油站的时候
从优先队列不断取出最大的油量加入总油量p (肯定取油量最多的呀)
如果优先队列取完了还是无法到达下一个加油站说明无法到达城镇

加油站全部经过之后还要再判断能否城镇,过程和前面的方法一样不够就不断取油
正因为方法是一样的,可以把城镇添加为最后一个加油站,合并到判断能否经过所有加油站的过程中

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<queue>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=1e6+5;
int n,l,p;
struct Node{
    int a,b;
}a[maxm];
int cmp(Node a,Node b){
    return a.a<b.a;
}
int main(){
    while(cin>>n){
        for(int i=1;i<=n;i++){
            cin>>a[i].a>>a[i].b;
        }
        cin>>l>>p;
        for(int i=1;i<=n;i++){
            a[i].a=l-a[i].a;//改为起点到加油站的距离
        }
        sort(a+1,a+1+n,cmp);//距离排序
        a[n+1].a=l;//假设终点为最后一个加油站
        int ans=0;
        priority_queue<int,vector<int>,less<int> >q;
        for(int i=1;i<=n+1;i++){//判断能否经过所有加油站,其实也就是能否到达终点
            if(p>=a[i].a){//如果能够到达这个加油站就把油量加入优先队列
                q.push(a[i].b);
            }else{
                while(!q.empty()){//不断加油
                    if(p<a[i].a){
                        p+=q.top();
                        q.pop();
                        ans++;//加油次数加1
                    }else{
                        break;
                    }
                }
                if(p<a[i].a){//如果加完了还是到不了,那么就无法到达终点了
                    break;
                }
                q.push(a[i].b);
            }
        }
        if(p>=l){//能到达的话
            cout<<ans<<endl;
        }else{//不能到达
            cout<<-1<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/94722319