luogu2627 修剪草坪
dp[i]表示1~i最大效率
记一下前缀和
转移就是f[i]=max(f[i],f[j-1]-sum[j])+sum[i] (i-k<=j<=i)
发现括号里的只与j有关 开一个单调队列维护一下
#include<cstdio> #include<iostream> #define ll long long using namespace std; //#pragma GCC optimize ("O3") int n,k; ll e[100010]; ll dp[100010]; ll sum[100010]; ll q[200010],head,tail; ll num[200010]; long long calc(int a) { num[a]=dp[a-1]-sum[a]; while(head<=tail && num[q[tail]]<num[a])tail--; q[++tail]=a; while(head<=tail && q[head]<a-k)head++; return num[q[head]]; } //f[i]=max(f[i],f[j-1]-sum[j])+sum[i] (j 1~e) int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){scanf("%lld",&e[i]);sum[i]=sum[i-1]+e[i];} for(int i=1;i<=n;i++)dp[i]=calc(i)+sum[i]; cout<<dp[n]; }