[USACO13OPEN]燃油经济性Fuel Economy

来源:互联网 发布:网王之驯养玫瑰的知世 编辑:程序博客网 时间:2024/06/10 09:12

[USACO13OPEN]燃油经济性Fuel Economy

贪心

题解:

先特判-1和0.

在一个加油站x时,它往后G的范围内,如果:
1. 有比它费用小的加油站y,就在x加恰好能走到y的油,直接跳到y。
2. 没有。此时在x加满油,跳到范围内费用最小的加油站。

细节见代码。

Code:

#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>using namespace std;typedef long long ll;const ll N = 100005;const ll INF = 1e17;ll n,G,B,D,ans;struct Station{    ll p,c;    bool operator < (const Station &other) const { return p < other.p; }} o[N];ll nxt(ll s,ll lim){    for(ll i=s+1,to=N-1;i<=n;i++){        if(o[i].p-o[s].p > lim) return to;        if(o[i].c < o[s].c) return i;        if(o[i].c < o[to].c) to=i;    }}int main(){    freopen("a.in","r",stdin);    scanf("%lld%lld%lld%lld",&n,&G,&B,&D);    for(ll i=1;i<=n;i++) scanf("%lld%lld",&o[i].p,&o[i].c);    sort(o+1,o+1+n);    for(ll i=2;i<=n;i++) if(o[i].p-o[i-1].p>G){ puts("-1"); return 0; }    if(o[1].p>B || D-o[n].p>G){ puts("-1"); return 0; }    if(D<B){ puts("0"); return 0; }    if(o[n].p==D){ o[n].c=0; }    else{ n++; o[n].p=D; o[n].c=0; }    o[N-1].c=INF;    ll now=0, fuel=B, to=nxt(now,fuel);    now=to; fuel-=o[to].p;    for(ll i=1;i<n;i++){        to=nxt(now,G);        if(o[to].c > o[now].c){            ans+=(G-fuel)*o[now].c;            fuel=G-(o[to].p-o[now].p);         }        else{            ans+=(o[to].p-o[now].p-fuel)*o[now].c;            fuel=0;        }        now=to;    }    printf("%lld\n",ans);}
原创粉丝点击