数学考试
题目描述
今天qwb要参加一个数学考试,这套试卷一共有n道题,每道题qwb能获得的分数为ai,qwb并不打算把这些题全做完, 他想选总共2k道题来做,并且期望他能获得的分数尽可能的大,他准备选2个不连续的长度为k的区间, 即[L,L+1,L+2,....,L+k-1],[R,R+1,R+2,...,R+k-1](R >= L+k)。
###输入描述:
第一行一个整数T(T<=10),代表有T组数据接下来一行两个整数n,k,(1<=n<=200,000),(1<=k,2k <= n)接下来一行n个整数a1,a2,...,an,(-100,000<=ai<=100,000)
###输出描述:
输出一个整数,qwb能获得的最大分数
输入
2
6 3
1 1 1 1 1 1
8 2
-1 0 2 -1 -1 2 3 -1
输出
6
7
题目大意
n道题,不做完,做2k道,连续两个不重合长度为k的区间,分数最大
思路
dp+前缀和
1.先求前缀和
2.从前到后求出数组下标i前的最大k长度区间和,不断更新(前一个的最大和最当前的和进行比较)
3从后到前求出数组下标i后的最大k长度区间和,不断更新(后一个的最大和最当前的和进行比较)
4.枚举所有i的前后最大值的和,找出最大和
错误思路
先求最大的k长度区间和,再从两边找第二大的k长度区间和
错误原因:情况考虑不全。
/*#include<bits/stdc++.h>错误思路
using namespace std;
int num[2000005];
struct date{
int a;
int head;
int wei;
}sum[2000005];
bool cmp(date a,date b)
{
return a.a>b.a;
}
int main()
{
//n道题 每道ai分 不全部做完,做2k道题,分数尽可能大
//前缀和
//不重合的两个区间
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<2000005;i++)//初始化
{
num[i]=0;
sum[i].a=0;
sum[i].head=0;
sum[i].wei=0;
}
int n=0,k=0;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&num[i]);
}
for(int i=0;i<k;i++)
{
sum[0].a=sum[0].a+num[i];
}
sum[0].head=0;
sum[0].wei=k-1;
//printf("sum[0]=%d\n",sum[0]);
for(int i=1;i<n&&sum[i].wei<n;i++)
{
sum[i].a=sum[i-1].a+num[sum[i-1].wei+1]-num[sum[i-1].head];
sum[i].head=sum[i-1].head+1;
sum[i].wei=sum[i-1].wei+1;
}
sort(sum,sum+n,cmp);
int max=sum[0].a;
sum[0].a=0;
int maxn=0;
for(int i=0;i<n;i++)
{
if(sum[i].a>maxn)
{
if(sum[i].head>sum[0].wei||sum[i].wei<sum[0].head)
{
maxn=sum[i].a;
}
}
}
printf("%d\n",max+maxn);
}
return 0;
} */
#include<bits/stdc++.h>
using namespace std;
long long int sum[200005];
long long int f[200005];
long long int s[200005];
int main()
{
//dp记录下标i前最大的值,i后最大的值
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
long long ans=-1e18;
scanf("%d%d",&n,&k);
memset(f,-0x7f,sizeof(f)) ;
memset(s,-0x7f,sizeof(s));
for(int i=1;i<=n;i++)
{
scanf("%lld",&sum[i]);
sum[i]=sum[i]+sum[i-1];
}
for(int i=k;i<=n-k;i++)
{
f[i]=max(f[i-1],sum[i]-sum[i-k]);
}
for(int i=n-k+1;i>=k+1;i--)
{
s[i]=max(s[i+1],sum[i+k-1]-sum[i-1]);
}
for(int i=k;i<=n-k;i++)
{
ans=max(ans,f[i]+s[i+1]);
}
printf("%lld\n",ans);
}
return 0;
}
京公网安备 11010502036488号