一种算法是分治法:O(nlgn)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 using namespace std; 5 const int maxsize=1000001; 6 int a[maxsize],sum[maxsize],n,inf=(1<<30); 7 int b[maxsize]; 8 struct solution{ 9 int lpos,rpos,sum; 10 }; 11 solution find_crossing_subarray(int low,int mid,int high){ 12 int left_sum=-inf,right_sum=-inf; 13 int sum=0,max_left,max_right; 14 for(int i=mid;i>=low;i--){ 15 sum+=a[i]; 16 if(sum>left_sum){ 17 left_sum=sum; 18 max_left=i; 19 } 20 } 21 sum=0; 22 for(int i=mid+1;i<=high;i++){ 23 sum+=a[i]; 24 if(sum>right_sum){ 25 right_sum=sum; 26 max_right=i; 27 } 28 } 29 solution a; 30 a.lpos=max_left; 31 a.rpos=max_right; 32 a.sum=left_sum+right_sum; 33 return a; 34 } 35 solution find_maximum_subarray(int low,int high){ 36 if(low==high){ 37 solution s; 38 s.lpos=s.rpos=low; 39 s.sum=a[low]; 40 return s; 41 } 42 int mid=(low+high)/2; 43 solution left=find_maximum_subarray(low,mid); 44 solution right=find_maximum_subarray(mid+1,high); 45 solution middle=find_crossing_subarray(low,mid,high); 46 if(left.sum>=right.sum&&left.sum>=middle.sum) return left; 47 else if(middle.sum>=left.sum&&middle.sum>=right.sum) return middle; 48 else return right; 49 } 50 int main(){ 51 while(scanf("%d",&n)!=EOF&&n){ 52 for(int i=1;i<=n;i++) scanf("%d",&b[i]); 53 for(int i=1;i<=n;i++){ 54 a[i]=b[n-i+1]; 55 } 56 solution ans=find_maximum_subarray(1,n); 57 printf("%d %d %d ",ans.sum,n-ans.rpos,n-ans.lpos); 58 } 59 }
另外一种是DP法,O(n)
maxisum-subarray problem, in fact, is try to find subarray A[i...j] of array A[1..i...j..n](1<=i<=j<=n). And the problem is meaningful only when array A has both the positve value and negative elements.
considering the size of problem:
* if n==1, the problem is quite easy. A[1] is the right answer.
* if array A has more than one value, then we can use DP method to solve it.
considering the procedure has already checked the A[i-1], and is going to enter the i th check. then we can assume that we have already get the maximum subarray of the A[1...i-1]. Supposing the maxisum subarray of A[1..i-1] is A[p..i-1].
Then, our procedure is going to the ith check, because we have aleady get the solution of A[1..i-1], and we will move to check A[i]. So how the relationship between sum[i-1] and sum[i]? (sum[i] stores the sum of subarray that end in A[i]). From our experience:
* if sum[i-1]<0, then whatever the A[i] is, the sum of subarray A[p...i-1,i] must be smaller than that of subarray A[p..i-1]. so we modify the starting indice of maxisum array from 'p' to 'i'. And at the same time, we can know that the maxisum subarray of A[1...i] is notthe A[p...i] but the A[p...i-1]. so the value of maxisum remains the same: the sum of A[p...i].
* For another circumstance, if sum[i-1]>0, we can take two situations into consideration, if A[i]>0 too, obviously, we should let sum[i]=sum[i-1]+a[i]. then for A[i]<0? in fact, we also need to plus A[i] onto sum[i-1]. as we know, in the (i-1)th calculation, acoording to the above assumption, we have already found the solution to the maxisum subarray: A[p...i-1]. So although the sum of A[p...i-1] is higher than that of A[p...i], in fact, in each iteration, we compare the value of sum[i-1] and sum[i] to the maxinum and store the maxinum. So we let the sum[i-1]+A[i] has no matter to the maxinum.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4 const int maxsize=101;
5 int a[maxsize],sum[maxsize],n,inf=(1<<30);
6 void solve(){
7 if(n==0) return;
8 int ans=-inf;
9 sum[1]=a[1];
10 int left=1,right=1;
11 for(int i=2;i<=n;i++){
12 if(sum[i-1]>0){
13 sum[i]=sum[i-1]+a[i];
14 right++;
15 }
16 else{
17 sum[i]=a[i];
18 left=i;
19 }
20 if(sum[i]>ans) ans=sum[i];
21 }
22 printf("Subarray from indice %d->%d has the maximum sum: %d
",left,right,ans);
23 }
24 int main(){
25 while(scanf("%d",&n)!=EOF){
26 for(int i=1;i<=n;i++) scanf("%d",&a[i]);
27 solve();
28 }
29 return 0;
30 }