版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82595676
解析:
首先状态转移还是比较好想的。
令
表示考虑前
个时,选择第
个与不选第
个能够获得的最大效益。
我们维护一个
数组表示前缀和。
那么,状态转移方程也就呼之欲出了
显然可以使用单调队列优化。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define st static
inline
ll getint(){
re ll num=0;
re char c;
while(!isdigit(c=gc()));
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=gc();
return num;
}
int n,k;
ll sum[100002];
ll f[100002][2];
ll q[100002];
int head=1,tail=1;
signed main(){
n=getint();
k=getint();
for(int re i=1;i<=n;++i)sum[i]=sum[i-1]+getint();
for(int re i=1;i<=n;++i){
f[i][0]=max(f[i-1][0],f[i-1][1]);
while(q[head]<i-k&&head<=tail)++head;
f[i][1]=f[q[head]][0]-sum[q[head]]+sum[i];
while(f[i][0]-sum[i]>f[q[tail]][0]-sum[q[tail]]&&tail>=head)--tail;
q[++tail]=i;
}
cout<<max(f[n][0],f[n][1]);
return 0;
}