算法导论笔记ch4_分治策略_最大连续子数组之和

     求解递归式的方法:

      1. 带入法:猜想一个界,然后用数学归纳法证明这个界是正确的(看到这顿时感觉回到了中学笔推的时代);

      2. 递归树法:将递归转换为一颗树,其节点表示不同层次的调用产生的代价,然后用边界和技术来求解递归式;

      3. 主方法: 可求解如下公式递归式的界:T(n) = aT(n/b) + f(n),这里刻划了一个分治算法:生成a个子问题,每个问题的规模是原有规模的1/b,分解和合并花费的时间为f(n).

      例子:求最大连续子数组之和.

      解决方法:采用分治策略进行分解,最大连续子数组必然位于以下三个位置:中间位置的左边、中间位置的右边、横跨中间位置。分情况讨论之。  时间效率为O(n*log n)  

     代码如下:

int ClsAlgoriIntro::max_subarray_sum(const int A[],int Left,int Right,int &start,int &end,int &maxSum)  
{  
int MaxLeftSum,MaxRightSum;              //左、右部分最大连续子序列值。对应情况【1】、【2】  
int MaxLeftBorderSum,MaxRightBorderSum;  //从中间分别到左右两侧的最大连续子序列值,对应case【3】。  
int LeftBorderSum,RightBorderSum;  
int Center,i;  
if(Left == Right)
{
if(A[Left]>0)  
return A[Left];  
else  
return 0;  
}
Center=(Left+Right)/2;  
MaxLeftSum=max_subarray_sum(A,Left,Center,start,end,maxSum);  
MaxRightSum=max_subarray_sum(A,Center+1,Right,start,end,maxSum);    
MaxLeftBorderSum=0;  
LeftBorderSum=0;  
for(i=Center;i>=Left;i--)  
{  
LeftBorderSum+=A[i];  
if(LeftBorderSum>MaxLeftBorderSum)  
{
MaxLeftBorderSum=LeftBorderSum;  
start = i;
}
}  
MaxRightBorderSum=0;  
RightBorderSum=0;  
for(i=Center+1;i<=Right;i++)  
{  
RightBorderSum+=A[i];  
if(RightBorderSum>MaxRightBorderSum)  
{
MaxRightBorderSum=RightBorderSum; 
end = i;
}  
}  
int max1=MaxLeftSum>MaxRightSum?MaxLeftSum:MaxRightSum;  
int max2=MaxLeftBorderSum+MaxRightBorderSum;  
maxSum = max1>max2?max1:max2;  
return maxSum;  
}  




      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值