哈哈哈做题好快乐!!!
思路:
一开始我会想到求好所有区间的前缀和,然后O(n^2)的枚举更新最大值即可。这样铁定超时。
然后我就会这样想把所有区间和存起来然后降序,然后取第一个最大值,然后去找不与他重复的第二大值,时间复杂度O(nlogn)时间复杂度应该没问题,不过这样也是错的,因为有可能取了第一大值,然后第2,3大都与它有重复部分,你只能取第4大,然后可能第2,3大的值更优。所有这样也错了。
最后我们会发现区间和的值是不会被更新的,所以我们可以先预处理[i,n]的最大值,然后枚举所有区间直接取与它不重复部分的最大值,然后不断更新答案即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int maxn = 1e6 + 10;
const ll inf = 0x3f3f3f3f;
ll a[maxn],sum[maxn],ans[maxn],Max[maxn];
void solved(){
int t;cin>>t;
while(t--){
int n,k;cin>>n>>k;
for(int i = 1; i <= n; i++){
cin>>a[i];
sum[i] = sum[i - 1] + a[i];
}
int cnt = 1;
for(int i = 1; i + k - 1 <= n; i++){
ans[cnt++] = sum[i + k - 1] - sum[i - 1];
}
for(int i = 1; i <= maxn - 10; i++)Max[i] = -1e18;
for(int i = cnt - 1; i >= 1; i--){
Max[i] = max(ans[i],Max[i + 1]);
}
ll res = -1e18;
for(int i = 1;i + k < cnt; i++){
res = max(res,ans[i] + Max[i + k]);
}
cout<<res<<endl;
}
}
int main(){
solved();
return 0;
} 
京公网安备 11010502036488号