单调队列优化 DP。
设 (dp_i) 表示跳完前 (i) 个能量球所需的花费。
可得:(dp_i=max(dp_k-100 imes x+sum^{i}_{j=k+1} h_j))。
对此 DP 柿子进行化简:
[dp_i=max(dp_k-100 imes x+sum^{i}_{j=k+1} h_j)\dp_i=max(dp_k-100 imes x+sum_i-sum_k(sum 为前缀和))\dp_i=max(dp_k-sum_k)-100 imes x+sum_i
]
同时该 DP 柿子也要满足 (dp_kge 100 imes x)。
可以利用单调队列进行优化。
#include<bits/stdc++.h>
using namespace std;
const int N=2000010;
int dl[N+5],l=1,r=0;
int sum[N+5],dp[N+5];
int n,m;
int main() {
scanf("%d %d",&n,&dp[0]);
for(int i=1,x;i<=n;i++) {
scanf("%d",&x);
sum[i]=sum[i-1]+x;
}
l=1,r=1,dl[1]=0;
for(int i=1;i<=n;i++) {
while(l<=r&&dp[i]-sum[i]>dp[dl[r]]-sum[dl[r]])
r--;
dl[++r]=i;
while(l<=r&&dp[dl[l]]<100*i)
l++;
dp[i]=dp[dl[l]]-sum[dl[l]]-100*i+sum[i];
}
printf("%d
",dp[n]);
}