给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。
当所有整数均为负值时定义其最大子段和为0。 依此定义,所求的最优值为:
定义bj为从i到j元素和最大的值,其中i从1..j-1。那么max(bj)即为所求
由bj的定义易知,
当bj-1>0时bj=bj-1+aj,否则bj=aj。
由此可得计算bj的动态规划递归式bj=max{bj-1+aj,aj},1≤j≤n。 算法
int MaxSum(int n, int a) {
int sum=0; b=0; for (i=1;i<=n;i++) {
if (b>0) b+=a[i]; else b=a[i]; if (b>sum) sum=b; }
return sum; }
显然该算法的计算时间为O(n)
二分法:分为前段,中段和后段。中段要对前后的数字联合起来考虑
int MaxSum(int a[],int left ,int right)
{
int i,j,sum,center,leftsum,rightsum,s1,s2,lefts,rights;
sum=0;
if(left==right)
{
if(a[left]>0)sum=a[left];
else sum=0;
}
else
{
center=(left+right)/2;
leftsum=MaxSum(a,left,center);
rightsum=MaxSum(a,center+1,right);
s1=0;
lefts=0;
for(i=center;i>=left;i--)
{
c1++;
lefts+=a[i];
if(lefts>s1)s1=lefts;
}
s2=0;
rights=0;
for(j=center+1;j<=right;j++)
{
c1++;
rights+=a[j];
if(rights>s2)s2=rights;
}
sum=s1+s2;
if(sum<leftsum)sum=leftsum;
if(sum<rightsum)sum=rightsum;
}
return sum;
}
//蛮力算法/穷举法
int Manli(int a[],int n)
{
int i,j,sum=0,max=0;
for(j=0;j<n;j++)
{ sum=0;
for(i=j;i<n;i++)
{
c2++;
sum=sum+a[i];
if(max<sum)max=sum;
}
}
return max;
}