D - Maximum Sum on Even Positions

https://codeforces.com/contest/1373/problem/D

题意:给出一个序列(从0开始计数)让我们求出偶数位置的最大和

   我们最多可以执行一次让某个连续区间翻转的操作;

思路:模拟一下可知,奇数个数的翻转是无效的,所以只能偶数个数的翻转

   我们求出相邻位置的差,记录下来,这里就有两种情况

   我们通过一个序列来看这两种情况 0 1 2 3 4 5 6

   我们可以用(0,1)(2,3)(4,5)这样子进行

   也可以(1,2)(3,4)(5,6)

   所以把这两种情况分别列举

   然后就会得出另外一个序列 ,求这个序列的最大子段和即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=2e5+10;
 5 int b[maxn];
 6 int a[maxn];
 7 int len;
 8 ll cal(int n)
 9 {
10     ll sum,maxsum;
11     sum=maxsum=0;
12     for(int i=1;i<=n;i++){
13         sum+=1ll*a[i];
14         if(sum>maxsum) maxsum=sum;
15         else if(sum<0) sum=0;
16     }
17     return maxsum;
18 }
19 int main()
20 {
21     int T;
22     scanf("%d",&T);
23     while(T--){
24         int n;
25         scanf("%d",&n);
26         ll res=0;
27         for(int i=0;i<n;i++){
28             scanf("%d",&b[i]);
29             if(i%2==0) res+=1ll*b[i];
30         }
31         len=0;
32         for(int i=1;i<n;i+=2)
33             a[++len]=b[i]-b[i-1];
34         ll ans=cal(len);
35         len=0;
36         for(int i=2;i<n;i+=2){
37             a[++len]=b[i-1]-b[i];
38         }
39         ans=max(ans,cal(len));
40         res+=ans;
41         printf("%lld\n",res);
42     }
43     return 0;
44 }
View Code

 

posted @ 2020-07-23 16:29  古比  阅读(141)  评论(0编辑  收藏  举报