1013 数学考试 前缀和
链接:https://ac.nowcoder.com/acm/contest/24213/1013
来源:牛客网
题目描述
他想选总共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,(2<=n<=200,000),(1<=k,2k <= n)
接下来一行n个整数a1,a2,...,an,(-100,000<=ai<=100,000)
输出描述:
输出一个整数,qwb能获得的最大分数
分析
求出一段区间的两段相加后 最大的两个子区间
只要前缀和预处理,遍历的时候,保留i左边的最大k长的最大子区间,sum[i+k] - sum[i] 来得到右边的k长区间,用ans 对每个i 取最大值就可以了
易错点:
a[i] 是有可能是负的,所以mx 初始化成负无穷
//-------------------------代码----------------------------
#define int LL
const int N = 2e5+10;
int n,k;
int a[N],sum[N],b[N];
void solve()
{
memset(sum,0,sizeof sum);
cin>>n>>k;
fo(i,1,n) {
cin>>a[i];
sum[i] =sum[i-1] + a[i];
}
int mx = -0x3f3f3f3f3f3f3f3f;
int ans = -0x3f3f3f3f3f3f3f3f;
fo(i,k,n-k) {
b[i] = max(mx,sum[i] - sum[i-k]);
// dbb(sum[i] - sum[i-k],i-k,i);
mx = max(mx,b[i]);
int tt = sum[i+k] - sum[i];
ans = max(ans,tt + mx);
}
cout<<ans<<endl;
}
signed main(){
clapping();TLE;
int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}
/*样例区
*/
//------------------------------------------------------------