Vjios 1617 超级教主

https://vijos.org/p/1617

单调队列优化 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]);
}
原文地址:https://www.cnblogs.com/lajiccf/p/Vjios1617.html