标题
由题意看可知需要求出两端不连续区间,同时使两个区间的和最大:
区间求和问题可以想到一个常用算法:前缀和。区间 [l,r][l,r] 的和可以用 sum_r-sum_{l-1}sum r −sum l−1 方便地求出。
预处理序列的前缀和后,如何得知某个位置之前和之后的和最大的区间呢?我们可以使用线性 DPDP 求得。设 f1_if1 i 表示位置 ii 之前的最大区间和,f2_if2 i 表示位置 ii 之后的最大区间和。那么有:
f1_i=\maxf1 i =max {f1_{i-1}f1 i−1 ,sum_i-sum_{i-k}sum i −sum i−k } f2_i=\maxf2 i =max {f2_{i+1}f2 i+1 ,sum_{i+k-1}-sum_{i-1}sum i+k−1 −sum i−1 } 由于数据范围较大,需要开long longlonglong。注意 ff 数组初始化为负无穷。
时间复杂度:O(Tn)O(Tn)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005];
int main()
{
ios::sync_with_stdio(0);
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]+=a[i-1];
}
ll sum=-1e18,ans=-1e18;
for(int i=k;i+k<=n;i++)
{
sum=max(sum,a[i]-a[i-k]);
ans=max(ans,sum+a[i+k]-a[i]);
}
cout<<ans<<endl;
}
return 0;
}