[C++]用三種方法求最大子段和
阿新 • • 發佈:2018-10-16
規劃 amp pan 分治 一位 max 組成 所有 ret
問題描述:給定n個整數組成的序列,求其中子段和的最大值。當所有整數均為非負整數時定義其最大子段和為0
方法一:O(n2)用一個值存儲最大和,用枚舉所有和的方法,來與這個值比較並更新最大值。
1 int MaxSum(int n, int *a, int &besti, int &bestj) 2 { 3 int sum=0; 4 for(int i=0;i<n;++i) 5 { 6 int parts=0; 7 for(int j=i;j<n;++j) 8 { 9 parts+=a[i];10 if(parts>sum){ 11 sum=parts; 12 besti=i; 13 bestj=j; 14 } 15 } 16 } 17 return sum; 18 }
方法二:O(nlogn)分治,分別求兩邊的最大子段和,再從中間分開的位置向兩邊拓展求最大和,三個值比較得最大子段和
1 int MaxSubSum(int *a,int left,int right) 2 { 3 intsum=0; 4 if(left==right) sum=a[left]>0?a[left]:0; 5 else{ 6 int c=(right+left)/2; 7 int lsum=MaxSubSum(a,left,c); 8 int rsum=MaxSubSum(a,c+1,right); 9 int s1=0,lefts=0; 10 for(int i=c;i>=left;--i)//左 11 { 12 lefts+=a[i]; 13 if(lefts>s1) s1=lefts; 14 } 15 int s2=0,rights=0; 16 for(int i=c;i<=rights;--i)//右 17 { 18 rights+=a[i]; 19 if(rights>s1) s1=rights; 20 } 21 sum=s1+s2; 22 if(lsum>sum) sum=lsum; 23 if(rsum>sum) sum=rsum; 24 } 25 return sum; 26 } 27 int MaxSum(int n, int *a) 28 { 29 return MaxSubSum(a,0,n-1); 30 }
方法三:O(n)動態規劃,求到這一位時能達到得最大子段和
1 int MaxSum(int n,int *a) 2 { 3 int sum=0,parts=0; 4 for(int i=0;i<n;++i) 5 { 6 if(parts>0) parts+=a[i]; 7 else parts=a[i]; 8 if(parts>sum) sum=parts; 9 } 10 return sum; 11 }
[C++]用三種方法求最大子段和