Solution
由题意可知需要求两段不连续区间,使和最大。
区间求和问题可以想到一个常用算法:前缀和。区间 的和可以用
方便地求出。
预处理序列的前缀和后,如何得知某个位置之前和之后的和最大的区间呢?我们可以使用线性 求得。设
表示位置
之前的最大区间和,
表示位置
之后的最大区间和。那么有:
{
,
}
{
,
}
由于数据范围较大,需要开。注意
数组初始化为负无穷。
时间复杂度:。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int maxn=2e5+10;
ll t,n,k,ans,a[maxn],sum[maxn],f1[maxn],f2[maxn];
int main(){
cin>>t;
while(t--){
memset(f1,-0x7f,sizeof(f1));
memset(f2,-0x7f,sizeof(f2));
cin>>n>>k;
ans=-1e18;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=a[i]+sum[i-1];
}
for(int i=k;i<=n-k;i++)
f1[i]=max(sum[i]-sum[i-k],f1[i-1]);
for(int i=n-k+1;i>=k+1;i--)
f2[i]=max(sum[i+k-1]-sum[i-1],f2[i+1]);
for(int i=k;i<=n-k;i++)
ans=max(ans,f1[i]+f2[i+1]);
cout<<ans<<endl;
}
return 0;
} 也可以来我的博客看 https://www.luogu.com.cn/blog/taiqi/post-niu-ke-mei-ri-yi-ti

京公网安备 11010502036488号