题意:给出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;
}
京公网安备 11010502036488号