二分法

作者:baihacker
來源:http://hi.baidu.com/feixue http://hi.csdn.net/baihacker

二分原理:
設f是定義在[a, b]上的bool函數,且滿足性質若f(i) = true則f(i+1) = true.
那麼算法:
int l = a, r = b;
while (l <= r)
{
int mid = (l + r)/2;
if (f(mid)) r = mid - 1;
else l = mid + 1;
}
結束時一定有 l = r + 1;
那麼有
l = b + 1或者l是最小的使得f的值爲true的數.
同時
r = a - 1或者r是最大的使得f的值爲false的數.
如果我們定義f(b+1) = true;
那麼可以描述爲
l是最小的使得f的值爲true的數.
r是最大的使得f的值爲false的數.

在有序的序列x1,x2,x3,...,xn找到i,使得xi >= value
根據上面的原理:
a = 1, b = 1;
f(i) = xi >= value;

這就是stl中的lower_bound,類似地可以得到upper_bound.
總之,二分原理可以求出滿足單調性的函數的第一個滿足某條件的值.

應用1:
給定含有n個整數的序列,可以把這個序列分爲m個子序列.
對於每個子序列,定義這個序列上的數的和爲這個序列的權重.
所有子序列的權重中最大的稱爲這個劃分的權重.
最小的劃分權重是多大?

直接解決這個問題不好解決.
反過來思考,給定權重x,最少可以劃爲多少份,這個問題可以用貪心算法解決.
定義f(x) = 在權重x下最少的劃分份數 <= m.
顯然x太小的話,這個函數爲假false,x夠大的話,這個函數的值爲true.
找到第一個最少劃分份數 <= m的x,顯然有:
如果取x-1,那麼要至少分爲大於m部分,不合要求.
如果對於x的最少劃分剛好是m,顯然,這是最小權.
如果對於x的最少劃分小於m,留給讀者自己思考.

可以看出,利用二分原理可以把複雜的問題,轉換爲判定性問題.

應用2:
|v0 - x| + |v1 - x| + ... + |vN-1 - x| <= M.
給定v0, v1,...,vN-1,和M,求使得這個等滿足的x的個數.(都考慮整數)
解的可能的範圍是
[max - M, min + M]
當vi取值大,M也大的時候,顯然不能直接求解.

很顯然,如果存在解,肯定是連續的一段,只需要找出這一段的最小值和最大值.
就可以知道有多少個解了.
利用二分原理,可以自然地想到在[max - M, min + M]上二分出最小,最大值.
以最小值爲例f(x) = F(x) <= M,找到使f(x)爲真的第一個數.(F爲|v0 - x| + |v1 - x| + ... + |vN-1 - x|)
對應的最大值就是f(x) = F(x) <= M爲真的最後一個數,注意二分原理,令g(x) = !f(x)
就是g(x)爲假的最後一個數.(其實就是在二分過程中,把l,r交換一下,在結束以後取r而不是取l)
且慢,這裏滿足條件嗎?
f(x)=true則f(x+1)=true嗎?
顯然不一定滿足.

可以先求F的最小值點k,要麼最小值點滿足f(k)=true,要麼解不存在.
這樣就可以分別在[k-m, k], [k, k+m]上二分.

如何求最小值點,這個問題比較簡單,留給讀者自己思考.


應用3:
給定一定數量的錢,要配一臺電腦,電腦由若干個部件組成.每個部件有不同的檔次,
檔次低的便宜但是得到的性能值小.又假定用統一的性能值衡量每個部件,性能值
最小值的部件爲整體性能值.要求組裝出性能值最大電腦.

應用4:
求出第k個素數.

擴展:
類似二分的,還有三分求凸(凹)函數極值.
有的二分寫法是while (l < r)道理是一樣的,結束的時候l = r,可以類似地給出二分原理,他們的本質是一樣的.
直觀地理解二分原理,要求第一個滿足要求的值,就是在當前值滿足要求的時候往更小的找,
否則就往更大的找.
要找出最後一個滿足要求的,就是在當前值滿足要求的時候往更大的找,否則往更小的找.

應用1:
http://cs.scu.edu.cn/soj/problem.action?id=3166
應用2:
http://cs.scu.edu.cn/soj/problem.action?id=3253
應用3:
http://cs.scu.edu.cn/soj/problem.action?id=3202
應用4:
http://topic.csdn.net/u/20091015/22/8e4f2bb8-0a95-40c7-917f-400703298968.html

發佈了7 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章