问题:给定由n个整数(有可能是负整数)组成的序列(a1,a2,a3,....an),最大字段和问题(sum of largest sub-segment)要求该序列子段之和的最大值。例如,序列(-20,11,-4,13,-5,-2)的最大子段和为20。
分治策略:按照平衡子问题的原则,将序列分为前后两个长度相同的子序列。这会出现以下三种情况:1.最大子段和出现在前半个子序列中。2.最大子段和出现在后半个子序列中。3.最大子段和出现在中间。
算法实现:
int MaxSum(int a[],int left,int right){
int sum = 0,midsum = 0,leftsum = 0,rightsum = 0;
int i,s1,s2,center,lefts,rights;
if(left == right) sum = a[left];
else{
center = (left + right) / 2;
leftsum = MaxSum(a,left,center);//情况1
rightsum = MaxSum(a,center+1,right);//情况2
s1=0;lefts=0;//情况3
for(i = center;i >= left;i--){//找左边的最大和
lefts += a[i];
if(lefts > s1) s1 = lefts;
}
s2 = 0;rights = 0;
for(i = center + 1;i <= right;i++){//找右边的最大和
rights += a[i];
if(rights > s2) s2 = rights;
}
midsum = s1 + s2;
sum = midsum>leftsum ? midsum:leftsum;
sum = rightsum>sum ? rightsum:sum;
}
return sum;
}
测试:
int main(){
int a[10] = {1,5,-8,9,7,-1,-1,3,-6,5};
int sum = MaxSum(a,0,9);
cout<<"The MaxSum is: "<<sum<<endl;
return 0;
}
输出如下:
The MaxSum is: 17