[51nod1254]最大子段和 V2
2016-10-10 18:48
239 查看
N个整数组成的序列a[1],a[2],a[3],…,a
,你可以对数组中的一对元素进行交换,并且交换后求a[1]至a
的最大子段和,所能得到的结果是所有交换中最大的。当所给的整数均为负数时和为0。
例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
Output
输出交换一次后的最大子段和。
先考虑与左边的数字交换的情况。
枚举交换位置x,把交换后的段拆成x左边和x右边两部分算。
需要事先计算出前缀和、后缀和、后缀和的后缀最小值、(前缀和 - 前缀最大值)的前缀最小值。
和右边的数交换同理。。
View Code
,你可以对数组中的一对元素进行交换,并且交换后求a[1]至a
的最大子段和,所能得到的结果是所有交换中最大的。当所给的整数均为负数时和为0。
例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
Output
输出交换一次后的最大子段和。
先考虑与左边的数字交换的情况。
枚举交换位置x,把交换后的段拆成x左边和x右边两部分算。
需要事先计算出前缀和、后缀和、后缀和的后缀最小值、(前缀和 - 前缀最大值)的前缀最小值。
和右边的数交换同理。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cmath> 7 #define ll long long 8 #define ui unsigned int 9 #define ull unsigned long long 10 using namespace std; 11 const int maxn=50023,modd=1000000007; 12 ll mn1[maxn],mn2[maxn],_mn1[maxn],_mn2[maxn],pr[maxn],af[maxn],ans; 13 int prmx[maxn],afmx[maxn],a[maxn]; 14 int i,j,k,n,m; 15 16 int ra,fh;char rx; 17 inline int read(){ 18 rx=getchar(),ra=0,fh=1; 19 while((rx<'0'||rx>'9')&&rx!='-')rx=getchar(); 20 if(rx=='-')fh=-1,rx=getchar(); 21 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh; 22 } 23 24 int main(){ 25 n=read();prmx[0]=afmx[n+1]=-1e9; 26 for(i=1;i<=n;i++)a[i]=read(),pr[i]=pr[i-1]+a[i],prmx[i]=max(prmx[i-1],a[i]); 27 for(i=n;i;i--)af[i]=af[i+1]+a[i],afmx[i]=max(afmx[i+1],a[i]); 28 29 // mn1[1]=0,mn2[1]=pr[1]; 30 for(i=1;i<=n;i++) 31 mn1[i]=min(mn1[i-1],pr[i]-prmx[i]), 32 mn2[i]=min(mn2[i-1],pr[i]); 33 // _mn1 =0,_mn2 =af ; 34 for(i=n;i;i--) 35 _mn1[i]=min(_mn1[i+1],af[i]-afmx[i]), 36 _mn2[i]=min(_mn2[i+1],af[i]); 37 for(i=1;i<=n;i++) 38 //i=15,//printf(" %lld-%lld %lld-%lld\n",af[i+1],_mn2[i+1],pr[i-1],mn1[i-1]), 39 ans=max(ans,(af[i+1]-_mn2[i+1])+(pr[i-1]-mn1[i-1])), 40 ans=max(ans,(pr[i-1]-mn2[i-1])+(af[i+1]-_mn1[i+1])), 41 ans=max(ans,pr[i]-mn2[i]); 42 printf("%lld\n",ans); 43 }
View Code
相关文章推荐
- 51 nod 1254 最大子段和 V2(思维)
- [贪心+堆+链表] 51Nod1053 最大M子段和 V2
- 51 nod 1052 最大M子段和(DP)
- 51nod1053 最大M子段和 V2
- 【贪心+堆+链表】51Nod1053[最大M子段和 V2]题解
- 51nod 最大M子段和V2【贪心】【链表】【堆】
- 【循环数组最大子段和】51nod 1050 循环数组最大子段和
- 51 nod 1188 最大公约数之和 V2(狄利克雷卷积+线性筛法)
- 51 nod 1049 最大子段和
- 51nod 1254最大子段和V2
- 51 nod 1188 最大公约数之和 V2
- 51 nod 1049 最大子段和
- 51nod 最大M子段和 V1,V2,V3 dp 贪心 heap(bzoj2288)
- 51 node 1050循环数组最大子段和
- 51nod 1053 最大M子段和 V2 (链表 对经典dp进行优化)
- 最大子段和(51Nod 1049)、最小正子段和(51Nod 1065)、总结(最小子段和、最大子段和、最小正子段和)
- 【51nod1049】最大子段和
- 51Nod1053 最大M子段和V2 二分+DP
- 51Nod-1053-最大M子段和 V2
- 51nod 1053 最大M子段和 V2