[算法]NOI競賽:簡單分治及其應用(一)

分治算法是一種思想,所以比一般算法更難使用。

1.劃分問題(Divide):將原問題分成一系列子問題。

2.遞歸解決(Conquer):遞歸地解各子問題。若子問題足夠小,則可直接求解。

3.合併問題(Combine):將子問題的結果合併成原問題的解。

[算法]NOI競賽:簡單分治及其應用(一)

·給出一個長度為n的序列A.求一個和最大的連續子序列。也就是要找出一對l.r(1≤l≤r≤n).使得Ai+A(i+1)+…+A(r-1)+A,最大。

·n≤10^5(最大子序列問題)

·暴力枚舉:

枚舉l,r,對於每對l,r計算這段子序列的和,對所有結果取最大值即為答案。

暴力計算時間複雜度為O(n^3)。

一個優化是記錄前綴和,即記錄S[i]=A1+A2+…+Ai.那麼子序列[l.r]的和即為S[r]-S[l-1]。

前綴和優化後複雜度為0(n2)。

分治解法

·設F(L.R)表示L到R這段區間內的和最大的子序列,答案就是F(1.n)。

考慮分治,假設現在要計算F(L,R).設mid=(l+R)/2.可以先遞歸計算F(L,mid)

以及F(mid+1.R)。(劃分問題,遞歸解決)

·注意到對於一個子序列[L.rl.L≤l≤r≤R.若l≤mid

·由於這樣的子序列的和可以表示為(Ai+Ai+1+…+Amid)+(Amid+1+…+Ar)的形式,只需找到一個l使得Ai+.…+Amid最大,再找到一個r使得Amid+1+…+Ar最大,加起來即得到結果。

·將得到的結果與F(L.mid),F(mid+1.R)取最大值,即得到F(L,R)。(合併問題)

時間複雜度為O(nlogn)

-給出一個長度為n的序列A,輸出將它從小到大排序之後的結果。

-n≤10^5 (排序問題)

歸併排序

·假設現在要將區間[L,R]內元素的排序,借鑑之前的思想,我們可以令mid=(L+R)/2,先遞歸地將[L.mid]和[mid+1.R]內的元素分別排好序。

現在需要將兩邊的序列合併在一起,可以維護兩個指針p.q.一開始令p=L,q=mid+1.並建立一個序列B表示新的序列。若A[p]


分享到:


相關文章: