题目描述如下:
分析:
因为是求子序列,我们不难想到用前缀和,当j<i时,子序列为s[i]-s[j],接着如果有一个存在一个,当i固定时若有一个j<k<i;且s[j]>s[k],易得s[i]-s[j]<s[i]-s[k],s[j]将可被舍去,性质符合单调队列,由此可想到用单调队列解。
代码实现如下:
#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,sum[300005],q[300005],a[300005],ans=-99999;
int main()
{
cin>>n>>m;
int l=1,r=1;
sum[0]=0;
q[l]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=a[i]+sum[i-1];//先处理前缀和。
}
for(int i=1;i<=n;i++)
{
while(l<=r && q[l]<i-m)
l++;//保证长度小于m;
ans=max(ans,sum[i]-sum[q[l]]);//将原最大值与现在的子序列比较。
while(l<=r && sum[q[r]]>=sum[i])
r--;//维护单调队列,如果出现一个i>q[r],且s[i]<=s[q[r]],则可将q[r]舍去。
q[++r]=i;//入队
}
cout<<ans;
return 0;
}