第1次跳100米,得到200能量,消耗100能量,所以落地后拥有300能量。
第2次跳300米,吃到剩下的第3棵能量球,消耗拥有的300能量,得到400能量。
若第1次跳200米,第2次跳300米,最后剩余300能量。
对于10%的数据,有N≤10;
对于20%的数据,有N≤100;
对于40%的数据,有N≤1000;
对于70%的数据,有N≤100000;
对于100%的数据,有N≤2000000。
保证对于所有数据,教主都能吃到所有的能量球,并且能量球包含的能量之和不超过2^31-1。
分析:单调队列。。之前脑子抽了一直输出dp[n-1]。。。状态转移方程看代码领悟就好~
#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#define range(i,a,b) for(int i=a;i<=b;++i)
#define LL long long
#define rerange(i,a,b) for(int i=a;i>=b;--i)
#define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
using namespace std;
const int MXN=(int)2e6+5;
int sum[MXN],dp[MXN],que[MXN],n;
void init(){
cin>>n>>dp[0];
range(i,1,n){
cin>>sum[i];
sum[i]+=sum[i-1];
}
que[1]=0;
}
void solve(){
int l=1,r=1;
range(i,1,n){
while(dp[que[l]]<i*100)++l;
dp[i]=dp[que[l]]-sum[que[l]]+sum[i]-i*100;
while(r>=l&&dp[que[r]]-sum[que[r]]<=dp[i]-sum[i])--r;
que[++r]=i;
}
cout<<dp[n]<<endl;
}
int main() {
init();
solve();
return 0;
}
View Code