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