哈哈哈做题好快乐!!!
思路:
一开始我会想到求好所有区间的前缀和,然后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; }