AcWing135. 最大子序和
/*
数组没开够,爆零两行泪
longlong开成int,爆零两行泪
多组忘清空,爆零两行泪
dp 没初值,爆零两行泪
深搜没边界,爆零两行泪
广搜忘出队,爆零两行泪
输入没加 &,爆零两行泪
模数没看见,爆零两行泪
-1 不输出,爆零两行泪
越界不特判,爆零两行泪
线段树开一倍,爆零两行泪
无向变有向,爆零两行泪
题意没审清,爆零两行泪
文件名起错,爆零两行泪
调试忘删除,爆零两行泪
没用freopen,爆零两行泪
*/
#include<bits/stdc++.h>
using namespace std;
const int N=300010;
int n,m;
int s[N],q[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&s[i]);
s[i]+=s[i-1];
}
int res=s[1];
int hh=0,tt=0;
for(int i=1;i<=n;i++){
if(q[hh]<i-m) hh++;
res=max(res,s[i]-s[q[hh]]);
while(hh<=tt&&s[q[tt]]>=s[i]) tt--;
q[++tt]=i;
}
printf("%d\n",res);
return 0;
}
/*
考虑按照子序列结尾进行分类
(1,2,3,k,n) 类
再从这几类中找到最优解
考虑ans[k],在a[k]~a[k-m]寻找
再考虑求区间和,预处理前缀和s[k]
可知ans[k]=min(s[k]-s[k-j]),k∈[1,m];
考虑用单调队列求解
复杂度O(n)
注意:子序列长度至少为1
*/