在分治策略中,我們遞迴的求解乙個問題,在每層遞迴中應用如下三個步驟:
分解(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
3for i =mid downto low
4 sum = sum+a[i]
5if sum > left-sum
6 left-sum =sum
7 max-left =i
8 right-sum = -∞
9 sum = 0
10for j = mid+1
to high
11 sum = sum +a[j]
12if sum > right-sum
13 right-sum =sum
14 max-right =j
15return (max-left , max-right , left-sum + right-sum)
有了乙個線性時間的find-max-crossing-subarray在手,我們就可以設計求解最大子陣列問題的分治演算法的偽**了:
find-maximum_subarray(a , low , high)1if high ==low
2return
(low , high , a[low])
3else 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)
7if left-sum ≥ right-sum and left-sum ≥ cross-sum
8return (left-low,left-high,left-sum)
9 elseif right-sum ≥ left-sum and right-sum ≥ cross-sum
10return (right-low,right-high,right-sum)
11else
return (cross-low,cross-high,cross-sum)
演算法導論 第四章 分治策略 (6)分治策略概述
當子問題足夠大,需要遞迴求解時,稱之為遞迴情況。當子問題變得足夠小,不再需要遞迴時,我們說遞迴已經 觸底 進入了基本情況。遞迴式與分治方法是緊密相關的,因為使用遞迴式可以很自然的刻畫分治演算法的執行時間。乙個遞迴式就是乙個等式或不等式,它通過更小的輸入上的函式值來描述乙個函式。子問題的規模不必是原問...
第四章 分治策略 最大子陣列問題
最大子陣列問題 方法一 暴力求解方法 我們可以很容易地設計出乙個暴力方法來求解本問題 簡單地嘗試沒對可能的子陣列,共有o n2 種 includeusing namespace std define int min 0x80000000 int main int i,j int sum 0,maxs...
工程導論第四章總結
1.創造力的 洗創造力 於想象力,這也是科學巨人愛因斯坦說 想象力比知識更重要 瑟的原因。數百年前達文西是乙個充滿想象力的藝術家 科學家 醫學家及工程師。他早就構思了人類的飛行器,雖然當時的工程技術無法實現該發明,但卻為後來的人們提供了無限的遐想,如今人不們已經把達文西的設計變成了現實。另一方面,達...