CF33C Wonderful Randomized Sum(贪心+思维)

题意:给你一个数字序列,你可以选择它的一些前缀或后缀(可能是空的)中的每个数字都乘以-1。前缀和后缀可以交叉也可以为空。问能得到的最大序列和是多少。

假设这个序列分成了三部分:A(前缀)+B(重合)+C(后缀)  S(序列的和)=A+B+C。重合部分,乘以-1两次,值不变,就相当于没有操作。而-(A+C)+B是更改后的序列和,而之前A+B+C=S,那么可以变成:-(S-B)+B=2*B-S(因为重合部分不变,而且是连续的所以最好寻求S与B的关系)。求这个最大值,S固定,那么只要保证B最大就好了。B如何保证最大?可以知道最大的B就是最大子序列的和。结果输出2*maxx-sum即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e5+10;
 6 int main()
 7 {
 8     int a[maxn];
 9     int sum=0,n;
10     cin>>n;
11     for(int i=1;i<=n;i++)
12     {
13         scanf("%d",&a[i]);
14         sum+=a[i];
15     }
16     int maxss=0,curs=0;
17     for(int i=1;i<=n;i++)//求最大连续子序列的和
18     {
19         curs+=a[i];
20         if(curs<0)
21         curs=0;
22         maxss=max(maxss,curs);
23     }
24     int ans=2*maxss-sum;
25     cout<<ans;
26     return 0;
27 }

posted on 2020-04-18 17:37  轻描淡写ぃ  阅读(173)  评论(0编辑  收藏  举报

导航