采用分治法求解
/*
*采用分治法实现最大子段和
* 将问题分为求左边一半的子段和,右边一半的子段和,还有可能是左边和右边相邻的子段和
* 1-n 分为1-n/2, n/2+1---n, m--n/2 n/2+1--k
*
*/
public static int max_sub(int[] a,int start, int end)
{
int center,left_max,right_max,sum,left_sum,right_sum;
//根据中间划分两段
center = (start+end)/2;
// 终止条件,负数取零
if(start==end){
return a[start]>0?a[start]:0;
}else {
// 递归左边最大子段和
left_max=max_sub(a,start,center);
// 递归右边最大子段和
right_max=max_sub(a,center+1,end);
// 最大子段和可能经过中间
sum=0;
left_sum=0;
for(int i=center;i>=start;i--) {
sum+=a[i];
if(sum>left_sum)
left_sum=sum;
}
sum=0;
right_sum=0;
for(int i=center+1;i<=end;i++){
sum+=a[i];
if(sum>right_sum)
right_sum=sum;
}
sum=right_sum+left_sum;
// 取三种情况最大值为最大子段和返回值
if(sum<left_max)
sum=left_max;
if (sum<right_max)
sum=right_max;
return sum;
}
}
利用动态规划求解
/*
*****************************
* 动态规划解决最大子段和
* 数组元素b[j]=max(a[i]+a[i+1]+..+a[j]),其中1<=i<=j,并且i<=j<=n。
* 则所求的最大子段和为max b[j],1<=j<=n。
*/
public static int dy_max_sub(int[] a,int start,int end)
{
int max;
int[] b = new int[a.length];
max=b[0]=a[0];
for(int i=start+1;i<=end;i++)
{
if(b[i-1]>0)
b[i]=b[i-1]+a[i];
else
b[i]=a[i];
if(b[i]>max)
max=b[i];
}
return max;
}