51nod1288 汽油补给

来源:互联网 发布:艾斯臣鞋子怎么样知乎 编辑:程序博客网 时间:2024/04/28 22:52

这里写图片描述
这不是就noip旅行家的预算吗。只不过这个每公里消耗一升油,感觉更简单了些。
贪心,每次找一个点后面第一油价比它低的点,想办法到那里让油全部用完。找它后面第一个比它价格低的点可以用单调栈处理。

#include<stdio.h>#include<stack>#include<iostream>using namespace std;typedef unsigned long long ll;const int N = 200000;ll d[N], p[N], pre[N];ll t, n, k, top;ll s[N];ll dfs(ll l, ll r){    ll pos = l;    ll ans = 0;    while(pre[pos] <= r){        int i = pre[pos];        if(k >= d[i] - d[pos]) {            k -= d[i] - d[pos];            pos = i;            continue;        }        if(d[i] - d[pos] <= t){            ans += (d[i] - d[pos] - k) * p[pos];            k = 0;            pos = i;        }else {            ans += (t - k) * p[pos];            k = t - (d[pos + 1] - d[pos]);            pos++;        }    }     return ans; }int main(){    //freopen("7_in.txt", "r", stdin);    ll ok = 0;    scanf("%lld%lld", &n, &t);    for(ll i = 0; i < n; i++){        scanf("%lld%lld", &d[i + 1], &p[i]);        if(d[i + 1] > t) ok = 1;        d[i + 1] += d[i];    }    for(int i = n - 1; i >= 0; i--){        while(top && p[i] < p[s[top]]){            top--;        }        if(top == 0) pre[i] = n;        else pre[i] = s[top];        s[++top] = i;    }    pre[n] = n + 1;    if(ok) puts("-1");    else printf("%lld\n", dfs(0, n));    return 0;}
原创粉丝点击