数学考试(前缀和)

链接:https://ac.nowcoder.com/acm/problem/15553
来源:牛客网

题目描述

今天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能获得的最大分数
示例1

输入

2
6 3
1 1 1 1 1 1
8 2
-1 0 2 -1 -1 2 3 -1

输出

6
7
 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 #define mst(a) memset(a,0,sizeof(a))
 5 const int INF = 0x3f3f3f3f;
 6 const LL LINF = 0x3f3f3f3f3f3f3f3f;
 7 const double eps = 1e-8;
 8 const int mod = 1e9+7;
 9 const int maxn = 2e5+10;
10 using namespace std;
11 
12 LL sum[maxn];
13 LL MAX[maxn];//位置i前,长度为k的区间的最大值
14 LL rMAX[maxn];//位置i后,长度为k的区间的最大值
15 
16 int main()
17 {
18     #ifdef DEBUG
19     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
20     #endif
21     
22     int T;
23     scanf("%d",&T);
24     while(T--)
25     {
26         mst(sum);
27         memset(MAX,-LINF,sizeof(MAX)); memset(rMAX,-LINF,sizeof(rMAX));
28         int n,k;
29         scanf("%d %d",&n,&k);
30         for(int i=1;i<=n;i++)
31         {
32             LL x;
33             scanf("%lld",&x);
34             sum[i] = sum[i-1]+x;
35         }
36         for(int i=k;i<=n;i++)
37             MAX[i]=max(MAX[i-1],sum[i]-sum[i-k]);
38         for(int i=n-k+1;i>=k;i--)
39             rMAX[i]=max(rMAX[i+1],sum[i+k-1]-sum[i-1]);
40         LL ans = -LINF;
41         for(int i=k;i<=n-k;i++)
42             ans=max(ans,MAX[i]+rMAX[i+1]);
43         printf("%lld
",ans);
44     }
45     
46     return 0;
47 }

--

原文地址:https://www.cnblogs.com/jiamian/p/13192432.html