1. 程式人生 > >[C++]用三種方法求最大子段和

[C++]用三種方法求最大子段和

規劃 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     int
sum=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++]用三種方法求最大子段和