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

问题描述:给定n个整数组成的序列,求其中子段和的最大值。当所有整数均为非负整数时定义其最大子段和为0


方法一:O(n²)用一个值存储最大和,用枚举所有和的方法,来与这个值比较并更新最大值。

 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 }
原创供学习参考使用,转载请注明出处http://www.cnblogs.com/cuphoria/ @jm_epiphany
原文地址:https://www.cnblogs.com/cuphoria/p/9800147.html