题意:给出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;
}