分治 & 递归式求解

        当要求解的一个输入规模为n且取值又相当大的问题是,直接求解往往比较困难,有的甚至根本没法直接求出。正确的方法是,每当遇到这类问题时,首先应仔细分析问题本身所具有的特性,然后根据这些特性选择适当的设计策略来求解。在将这n个输入分成k个不同子集合的情况下,如果能得到k个不同的可独立求解的子问题(具有重复子问题的用动态规划求解),其中1<k≤n,而且在求出了这些子问题的解之后,还可以找到合适的方法把它们合并成整个问题的解,那么,可考虑使用分治法来求解。如果子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型的子问题。

1. 步骤

在分治策略中,我们递归地求解一个问题,在每层中应用如下三步:

(1) 分解:将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小;

(2) 解决:递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解;

(3) 合并:将子问题的解组合成原问题的解。

2. 最大子数组问题

           给定一个由正负整数组成的顺序表,求解一组连续的数使其和最大。例如给定一组数据-1,2,3,-2,5,连续数s = {2,3,-2, 5}取得最大值8,其它的连续数之和均小于8,则s为我们要的连续数。

设A[i, j]表示从i开始到j结束的顺序表,m[i, j]表示从第i个数到第j个数中连续数的最大和。

2.1 方法一:暴力破解

计算每一种情况的和,然后记录取得最大值时的连续数。该方法共检测n(n+1)/2种情况,因此时间复杂度为O(n2)。

2.2 方法二:分治

(1) 分解:将问题A[i, j]从中间划分开,分成左右两部分:A[i, middle]和A[middle, j],对应的最大值分别为A[i, middle]和A[middle, j],其中middle=(i+j)/2;

(2) 解决:若问题的规模j-i为0时,直接返回第i个数,即当前规模的最大值;

(3) 合并:A[i, j]取得的最大值m[i, j]为左侧m[i, middle]、右侧m[middle, j]对应的最大值和包含中间值的最大值中的最大值。

运行时间T(n)的递归式为:


求解递归式可得T(n) = O(nlogn),优于暴力破解方法的O(n2)。

3. 递归式求解

递归式的求解共有三种方法:代入法、递归树和主方法。

3.1 代入法

代入法共分为两步:

(1) 猜测解的形式;

(2) 用数学归纳法求出解中的常数,并证明解是正确的。

例如:T(n) = 2T(n/2)+n

(1) 猜测T(n) ≤ cnlgn;

(2) 证明:令m=n/2,有T(n/2) ≤ cn/2lg(n/2);

则:

T(n) ≤ 2(cn/2lg(n/2))+n

 ≤ cnlg(n/2) + n

    = cnlgn – cnlg2 + n

  = cnlgn – cn + n

≤     cnlgn

3.2 递归树

               例T(n) = 3T(n/4) + O(n2),其递归树如图3-1所示。图中结点中的数字表示合并问题解的代价,因此该递归式的解为图中所有结点中数字之和。易得该递归树最多有log4n+1层,如图中左侧所示;另外图右侧表明了每层的数字之和,则递归式T(n) = 3T(n/4) + O(n2)的解为T(n) = Ο(n2),详细结算过程如下:



图3-1 T(n) =3T(n/4) + O(n2)的递归树

3.2 主方法(The master method


参考:算法导论

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值