分治法解 “最大子序列和”

short135 2009-03-10 09:43:01

static int MaxSubSum(const int a[],int Left,int Right)
{
int MaxLeftSum,MaxRightSum;
int MaxLeftBorderSum,MaxRightBorderSum;
int Center;
if(Left==Right)
if(a[Left]>0)
return a[Left];
else
return 0;

Center=(Left+Right)/2;
MaxLeftSum =MaxSubSum(a,Left,Center); //第一句
MaxRightSum=MaxSubSum(a,Center+1,Right);//第二句

MaxLeftBorderSum=0;LeftBorderSum=0;
for(i=Center;i>=Left;i--)
{
LeftBorderSum+=a[i];
if(LeftBorderSum>MaxLeftBorderSum)
MaxLeftBorderSum=LeftBorderSum;
}

MaxRightBorderSum=0;RightBorderSum=0;
for(i=Center+1;i<=Right;i++)
{
RightBorderSum+=a[i];
if(RightBorderSum>MaxRightBorderSum)
MaxRightBorderSum=RightBorderSum;
}
return Max3(MaxLeftSum,MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum);
}

int MaxSubsequenceSum(const int a[], int n)
{
return MaxSubSum(a,o,n-1);
}


MaxLeftSum 求序列前半部分最大子序列和
MaxRightSum求序列后半部分最大子序列和
MaxLeftBorderSum 表示包含序列前半部分最后一个元素的最大值
MaxRightBorderSum表示包含序列后半部分第一个元素的最大值


个人分析:
第一句不停调用函数MaxSubSum()直至Left==Right 递归结束
将值0或a[Left]返回MaxLeftSum
返回上次MaxSubSum()递归调用,执行第二句
继续递归调用? 就是到这个地方比较模糊

希望能有人能详细的将递归过程分析一下,两个递归语句是如何执行的
...全文
588 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
cattycat 2010-06-13
  • 打赏
  • 举报
回复
其实这个当Left=Right返回后,第二句的Right其实就是center的二倍。然后下面的句子是看这两个区间的中间部分。
可以逆向考虑,整个区间分成0-mid,mid-right, 中间部分的再计算一下,第二次递归就是0-mid再划分成0-1/4mid,1/4mid-1/2mid部分,这个的中间部分;然后是右边被划分,这样依次划分的。
shen151 2010-06-13
  • 打赏
  • 举报
回复
LS几个朋友说的都很好,本来就是逆向思维的,和必过多去思考。
sunnyplain 2009-03-11
  • 打赏
  • 举报
回复
楼上说的对,看递归程序不要老想着它是怎么执行的,看懂汉诺塔那个是怎么执行的就够了
你只要假设第一句求出了前半段的最大子序列和,第二句求出了后半段的,而下面的合并过程在上面假设的基础上能正确执行。再知道一点,就是终止条件,并且终止处是满足上面假设的。理解这些就够了,其实和数学归纳法是一个道理。
whuyotc 2009-03-11
  • 打赏
  • 举报
回复
mark一个
xuguod20042576 2009-03-11
  • 打赏
  • 举报
回复
最主要的是理解递归的原理呀.
bo.cui 2009-03-11
  • 打赏
  • 举报
回复
好困~~~

理解递归原理就好了~

最要紧的:你要信任递归!
ltc_mouse 2009-03-10
  • 打赏
  • 举报
回复
理解递归,不应该将函数一层一层展开,即针对代码中的"第一句",没必要看成"不停调用函数MaxSubSum()直至Left==Right 递归结束"
而是直接假设MaxSubSum是正确的,它求得了序列前半部分最大子序列和~
当然,需要递归终止条件,就是只有一个数时,Left=Right,得到长度为1或0的子序列~~

就像数学归纳法,先证明命题f(n)对于初始条件如n=1成立,然后假设命题f(n)对于n=2,3,...,k成立,只要求证f(n)对k+1也成立一样
这里的初始条件就是只有1个数,Left=Right~
  • 打赏
  • 举报
回复
最讨厌递归。。因为稍微复杂点的我就开始晕。。
mark先。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧