#include <string.h>
#include <stdio.h>
/**
* 计算 a中从 left 到 right的最大子序列
* l r为计算得到的子序列位置
*/
int maxSub(int *a, int left, int right, int *l, int *r) {
if (left == right) {
*l = left;
*r = left;
return a[left];
}
if (left + 1 == right) {
if (a[left] > 0 && a[right] > 0) {
*l = left;
*r = right;
return a[left] + a[right];
} else if (a[left] > a[right]) {
*l = left;
*r = left;
return a[left];
} else {
*l = right;
*r = right;
return a[right];
}
}
int center = (left + right) / 2;
int ll = 0, lr = 0;
int sum1 = maxSub(a, left, center, &ll, &lr);
int rl = 0, rr = 0;
int i;
int sum2 = maxSub(a, center + 1, right, &rl, &rr);
if (sum1 > 0 && sum2 > 0) {
//计算中间数据
int tempsum = 0;
int max = rl - 1;
i = lr + 1;
for (; i <= max; i++) {
tempsum += a[i];
}
if (sum1 > sum2) {
if (sum2 + tempsum > 0) {
*l = ll;
*r = rr;
return sum1 + sum2 + tempsum;
} else {
*l = ll;
*r = lr;
return sum1;
}
} else {
if (sum1 + tempsum > 0) {
*l = ll;
*r = rr;
return sum1 + sum2 + tempsum;
} else {
*l = rl;
*r = rr;
return sum2;
}
}
} else if (sum1 > sum2) {
*l = ll;
*r = lr;
return sum1;
} else {
*l = rl;
*r = rr;
return sum2;
}
}
int main(void) {
int a[10] = {-4,-3,-3,3,0,0,-4,-3,-9,-1};
int l=0,r=9;
int sum=maxSub(a,0,9,&l,&r);
printf("max from %d to %d sum is %d",l,r,sum);
printf("\n");
}
在计算机算法设计与分析中 给出了一个动态规划算法 如下
int MaxSub_(int n,int *a){
int sum=0,b=0;
int i=0;
for(;i<=n;i++){
if(b>0)
b+=a[i];
else
b=a[i];
if(b>sum)
sum=b;
}
return sum;
}
算法很简单 不过算法不能给出最大子段的位置 还有不能计算纯负数组成的序列
可以对算法稍微做下改动使支持全部由负数组成的序列
int MaxSub_(int n,int *a){
int sum=1,b=0;
int i=0;
int size=sizeof(int);
//获取最小整数
sum=sum<<(size*8-1);
printf("sum=%d %d",sum,size);
for(;i<=n;i++){
if(b>0)
b+=a[i];
else
b=a[i];
if(b>sum)
sum=b;
}
return sum;
}