探险

传送门

题目大意是,车子离城镇L单位长度,还有P升油,每开一个单位长度减1升,中途有n个加油站,每次能加一定数量的油,求最少加几次油能到目的地。油箱视为无限大。

或许你会想这样贪心:每次开车开到最远能行驶距离,在最后一个加油点加油,之后继续开,但是这个样例就把你卡死了。我们考虑这个题的关键所在就是,其实他不一定非要开到快没有油才加油,它要保证下一步油最多。

用mrclr大佬的话说,他其实可以开过了再回来加油(滑稽)

所以我们用一个堆来维护所走过的路程中,使你获得最多行走距离的加油站,每次把能走到的压到堆中,取堆顶即可。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('
')

using namespace std;
typedef long long ll;
const int M = 200005;
const int N = 1005;
const int INF = 2147483647;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

struct node
{
    int pos,val;
    bool operator < (const node &g) const
    {
        return val < g.val;
    }
}a[M];

int T,n,l,p,g = 1,ans;
priority_queue <node> q;
bool flag = 0;

bool cmp(node a,node b)
{
    return a.pos < b.pos;
}

int main()
{
    T = read();
    while(T--)
    {
    n = read();
    rep(i,1,n) a[i].pos = read(),a[i].val = read();
    l = read(),p = read();
    rep(i,1,n) a[i].pos = l - a[i].pos;
    sort(a+1,a+1+n,cmp);
    while(!q.empty()) q.pop();
    ans = 0,flag = 0,g = 1;
    while(p < l)
    {
        while(a[g].pos <= p && g <= n) q.push(a[g++]);
        if(!q.empty()) p += q.top().val,ans++,q.pop();
        else
        {
        printf("-1
");
        flag = 1;
        break;
        }
    }
    if(!flag) printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/captain1/p/9853499.html