这不是就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;
}