算法导论-第四章-分治策略(速记)

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

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

解决(Conquer)步骤递归地求解出子问题,如果子问题的规模足够小,则停止递归,直接求解.

合并(Combine)步骤将子问题的解组合成原问题的解.

 

当子问题足够大,需要递归求解时,我们称之为递归情况(recursive case).

当子问题变得足够小,不再需要递归时,我们说递归已经"触底",进入了基本情况(base case).

 

最大子数组问题:

股票价格,买进卖出,寻找一段时期,使得从第一天到最后一天的股票价格净变值最大.

A[low..high]的任何子数组A[i..j]所处的位置必然是以下三种情况之一.

完全位于子数组A[low..mid]中,因此low ≤ i ≤ j ≤ mid.

完全位于子数组A[mid+1..high]中,因此mid < i ≤ j ≤ high.

跨越了中点,因此low ≤ i ≤ mid < j ≤ high.

FIND-MAX-CROSSING-SUBARRAY(A,low,mid,high)
1
left-sum = - 2 sum = 0 3 for i = mid downto low 4 sum = sum+A[i] 5 if sum > left-sum 6 left-sum = sum 7 max-left = i 8 right-sum = - 9 sum = 0 10 for j = mid+1 to high 11 sum = sum + A[j] 12 if sum > right-sum 13 right-sum = sum 14 max-right = j 15 return (max-left , max-right , left-sum + right-sum)

有了一个线性时间的FIND-MAX-CROSSING-SUBARRAY在手,我们就可以设计求解最大子数组问题的分治算法的伪代码了:

 

FIND-MAXIMUM_SUBARRAY(A , low , high) 
1
if high == low 2 return (low , high , A[low]) 3 else mid = ⎿(low + high)/2 4 (left-low , left-high , left-sum) = FIND-MAXIMUM-SUBARRAY(A , low , mid) 5 (right-low , right-high , right-sum) = FIND-MAXIMUM-SUBARRAY(A , mid+1 , high) 6 (cross-low , cross-high , cross-sum) = FIND-MAX-CROSSING-SUBARRAY(A , low , mid , high) 7 if left-sum ≥ right-sum and left-sum ≥ cross-sum 8 return (left-low,left-high,left-sum) 9 elseif right-sum ≥ left-sum and right-sum ≥ cross-sum 10 return (right-low,right-high,right-sum) 11 else return (cross-low,cross-high,cross-sum)

 

 

 

 

 

posted @ 2019-03-06 14:46  愿你能再次遇到你重要的人  阅读(196)  评论(0编辑  收藏  举报