题意:给你一个数字序列,你可以选择它的一些前缀或后缀(可能是空的)中的每个数字都乘以-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 }