最大子段和

来源:互联网 发布:数据库管理数据的优点 编辑:程序博客网 时间:2024/05/20 13:13
最大子段和 
给定由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;

}


原创粉丝点击