问题描述:
给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。
当所有整数均为负值时定义其最大子段和为0。
依此定义,所求的最优值为:
例如,当(a1,a2 , a3 , a4 , a5 ,a6)=(-2,11,-4,13,-5,-2)时,
最大子段和为:
11+(-4)+13 =20
一个最简单的算法是:
int maxdata[9]={-2, 1, -3, 4, -1, 2, 1, -5, 4};
int maxsubarray(){
int max_ending_here;
int max_so_far;
max_ending_here=0;
max_so_far=0;
for(int i=0;i<9;i++){
max_ending_here = maxvalue(0, max_ending_here + maxdata[i]);
max_so_far = maxvalue(max_so_far, max_ending_here);
}
return max_so_far;
}
如果采用分治法,时间复杂度为O(nlogn),代码如下:
int MaxSubSum(int * Array, int left, int right){
int sum=0;
int i;
if(left==right){
if(Array[left]>0)
sum=Array[left];
else
sum=0;
}else{
int center=(left+right)/2;
int leftsum=MaxSubSum(Array, left, center);
int rightsum=MaxSubSum(Array, center+1, right);
int s1=0;
int lefts=0;
for(i=center;i>=left;i--){
lefts=lefts+Array[i];
if(lefts>s1)
s1=lefts;
}
int s2=0;
int rights=0;
for(i=center+1;i<=right;i++){
rights=rights+Array[i];
if(rights<s2)
s2=rights;
}
sum=s1+s2;
if(sum<leftsum) sum=leftsum;
if(sum<rightsum) sum=rightsum;
}
return sum;
}