EOJ 1855 - 远征

既然要加油次数最少,那么干脆一次油也不加,直接冲到底,如果不能到目的地,那么奶牛们有一次S/L大法(存档/读档)的机会,可以退回到之前某个路过的加油站加好油再次开始逃亡(如果没有这样的加油站,显然可怜的奶牛永远也到不了目的地)。那么,为了让加油次数最少,选择油最多的加油站是最合算的,因为显然加油站的距离对加油没有影响。

实现这个算法需要用到优先队列,经过的加油站入队,油用尽时出队一个加油继续向前,直到到达目的地或者无油可用为止。

#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
using namespace std;
map<int,int> station;
priority_queue<int> fuels;
int main()
{
    int n,t,f;
    cin>>n;
    for(int i=0; i<n; i++) {
        scanf("%d%d",&t,&f);
        station[t]=f;
    }
    station[0]=0;
    int stop=0,distance,fuel;
    cin>>distance>>fuel;
    int flag=1;
    if(n!=0) {
        for(auto i=station.rbegin(); i!=station.rend(); ++i) {//加油站按照距离逐次入队
            if(i->first>=distance)continue;
            fuel-=(distance-i->first);
            while(fuel<0) {//加油循环
                if(fuels.empty()) {
                    break;
                }
                fuel+=fuels.top();
                fuels.pop();
                stop++;
            }
            if(fuel<0) {//加油完毕还是没油,卒
                flag=-1;
                break;
            }
            fuels.push(i->second);
            distance=i->first;
        }
    } else {
        if(fuel<distance) {
            flag=-1;
        }
    }
    if(flag==-1) {
        cout<<"-1"<<endl;
    } else {
        cout<<stop<<endl;
    }
    return 0;
}



你可能感兴趣的:(优先队列,贪心)