最大连续和算法分析

来源:互联网 发布:油画棒 知乎 编辑:程序博客网 时间:2024/06/06 18:43

1.        描述:

给出一个长度为N的序列:a1,a2,……,an,求最大连续和。找到1=<I<=J<=N,使得ai+a(i+1)+……+aj尽量大。

2.        算法一:先求出所有的和S[1],S[2],……,ai+a(i+1)+……+aj=S[J]-S[I-1].

代码:

s[0]=0;

int best=a[1];

for(int i=1;i<=n;i++)

{

   s[i]=s[i-1]+a[i];

}

for(int i=1;i<=n;i++)

{

   for(int j=i;j<=n;j++)

    {

       best=max(best,s[j]-s[i-1]);

    }

}

4.        算法二:

int best=a[1];

for(int i=1;i<=n;i++)

{

   int sum=0;

   for(int j=i;j<=n;j++)

    {

       sum=sum+a[j];

       best=max(best,sum);

    }

}

5.        算法三:分治法

共三步:

划分问题:将问题的事例划分成子问题。把序列分成元素个数尽量相等的两半。

递归求解:递归解决子问题。分别求出完全位于左半或者完全位于右半的最佳序列。

合并问题:合并子问题的解得到原问题的解。求出起点位于左半,终点位于右半的最大连续和序列,并和子问题的最优解进行比较。

int maxsum(int *A,int x,int y) //返回数组在左闭右开区间[x,y)中的最大连续和

{

   int v,L,R,maxs;

   if(y-x==1)//只有一个元素,直接返回

    {

       return a[x];

    }

   int m=x+(y-x)/2;//分治第一步:划分成[x,m)和[m,y)

   maxs=max(maxsum(A,x,m),maxsum(A,m,y));//分治第二步:递归求解

   v=0;//分治第三步(1):开始从分界点往左求最大连续和:L

   L=a[m-1];

   for(int i=m-1;i>=x;i--)

    {

       L=max(L,v=v+a[i]);//赋值运算本身具有返回值

    }

   v=0;//分治第三步(2):开始从分界点往右求最大连续和:R

   R=A[m];

   for(int i=m;i<y;i++)

    {

       R=max(R,v=v+A[i]);

    }

   return max(maxs,L+R);//把子问题的解和L+R比较

}

关于分界点的计算:

运算符‘/’的取整是朝零方向的取整,x+(y-x)/2使得分界点总是靠近区间起点。

0 0
原创粉丝点击