题意:给出n道题的分数,给出一个k,要求2个不连续的长度为k的区间分数要最大。
这是一道比较好的前缀和+dp的题目。
由于只存在2个区间,dp1【i】表示i这个位置前面的最大值 dp2【i】表示i这个位置后面的最大值
我们只需要维护这2个dp数组即可,答案就是2个dp数组相加取max
区间为k的和用前缀和来处理
注意开long long
#include <bits/stdc++.h> #define INF 0x7f using namespace std; typedef long long ll; const int N=200000+100; ll t; ll n,k; ll a[N]; ll sum[N]; ll sum2[N]; ll dp[N]; ll dp2[N]; int main() { scanf("%lld",&t); while(t--) { memset(dp,-INF,sizeof(dp)); memset(dp2,-INF,sizeof(dp2)); scanf("%lld%lld",&n,&k); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); sum[1]=a[1]; for(int i=2;i<=n;i++) { sum[i]=sum[i-1]+a[i]; } sum2[n]=a[n]; for(int i=n-1;i>=1;i--) { sum2[i]=sum2[i+1]+a[i]; } for(int i=1;i<=k;i++)dp[i]=sum[i]; for(int i=k+1;i<=n;i++) { dp[i]=max(dp[i-1],sum[i]-sum[i-k]); } for(int i=n-k+1;i<=n;i++)dp2[i]=sum2[i]; for(int i=n-k;i>=1;i--) { dp2[i]=max(dp2[i+1],sum2[i]-sum2[i+k]); } // for(int i=1;i<=n;i++) // { // printf("%d%c",dp[i],i==n?'\n':' '); // } // for(int i=1;i<=n;i++) // { // printf("%d%c",dp2[i],i==n?'\n':' '); // } ll ans=-1e18; for(int i=k;i<=n-k;i++) { ans=max(dp[i]+dp2[i+1],ans); } printf("%lld\n",ans); } return 0; }