分治策略之最大子陣列

2021-07-23 04:30:29 字數 1388 閱讀 7734

分治策略是將父問題差分成的多個子問題,然後遞迴的方式解決子問題。整個思想和動態規劃類似,不過分治策略不要求最優解問題,而只是把父問題分解成子問題。步驟:

分解(divide)

先將問題劃分成子問題。子問題的形式與原問題相同。

解決(conquer)

遞迴解決問題,當問題縮小到一定程度就能夠直接求解。

合併(combine)

當最小子問題解決後,遞迴已經觸底回歸,逐漸將子問題答案合併成父問題解。

給乙個陣列a[0…n],假設a[s…t]是它的子陣列,那麼這個子陣列的所有元素加起來最大是多少?用數學語言形式化的描述就是:求0<=s<=t<=n 使得 a[s]+a[s+1] …. + a[t] 最大。

暴力求解:

暴力破解只需要遍歷陣列就能夠解決:

先假設最大子陣列從a[0]開始,接下來只需要從a[0]開始延伸a[0]  a[0]a[1]   a[0]a[1]a[2]…..

再假設最大子陣列從a[1]開始,接下來只需要從a[1]開始延伸a[1]  a[1]a[2]   a[1]a[2]a[3]…..

再假設最大子陣列從a[2]開始,接下來只需要從a[2]開始延伸a[2]  a[2]a[3]   a[2]a[3]a[4]…..

…….如此便把所有子陣列都考慮了一遍。

分治策略:

divide:

使用分治策略,我們盡量將父問題分解成規劃相等的子問題。所有找到陣列中間位置mid,將陣列分成兩個部分。即a[low,mid] 和 a[mid,high]。

在考慮下答案,很明顯,最後答案要不在a[low,mid]中,要不就在a[mid,high]中,或者橫跨兩個陣列(這是答案必定包含a[mid])。

conquer:

我們父問題分解成三個子問題。其中我們發現:

1、求a[low,mid]最大子陣列和和a[mid,high]最大子陣列和其實和父問題是一樣的形式,只不過規模不一樣。因此這兩個子問題我們只需要遞迴就能夠求解。

2、求橫跨兩個陣列(這是答案必定包含a[mid])最大子陣列和問題,這個問題與父問題形式是不同的,但是這個問題有個關鍵因素答案必定包含a[mid],因此我們只需要從a[mid]向兩邊延伸求和就能解出答案。

combine:

最終答案的合併就是遞迴的回歸,從最小子問題一直回歸到父問題。答案就直接解出。

code:

看函式的返回值:通過if語句找出三個子問題的最大陣列和再返回到父問題。是不是就是相當於把子問題的答案經過比較返回最大陣列和作為父問題的最優解。該問題其實就是動態規劃問題。

分治策略之最大子陣列問題

問題 乙個整數陣列中的元素有正有負,在該陣列中找出乙個連續子陣列,要求該連續子陣列中各元素的和最大,這個連續子陣列便被稱作最大連續子陣列。比如陣列的最大連續子陣列為,最大連續子陣列的和為5 2 1 2 8。一 暴力解法 include using namespace std class soluti...

分治策略之最大子陣列問題

最大子陣列,即子陣列中的各個元素相加的和是所有子陣列中最大的。假設最大子陣列為 ai.aj 則必然是以下三種情況 1 完全位於子陣列a low.mid 中 2 完全位於子陣列a mid 1.high 中 3 跨越了中點low i mid j high 如果暴力求解的話,時間複雜度為 n int fi...

分治策略之最大子陣列問題

問題 乙個整數陣列中的元素有正有負,在該陣列中找出乙個連續子陣列,要求該連續子陣列中各元素的和最大,這個連續子陣列便被稱作最大連續子陣列。比如陣列的最大連續子陣列為,最大連續子陣列的和為5 2 1 2 8。一 暴力解法 include using namespace std class soluti...