演算法基礎 二分答案

2021-09-25 23:52:28 字數 1918 閱讀 5279

二分包括整數二分和浮點數二分,整數二分有兩種情況(兩個模板),浮點數二分只有一種情況(乙個模板)。

二分本質:如果能找到乙個性質將區間一分為二,一半滿足性質,一半不滿足性質,二分就可以尋找這個性質的邊界(滿足性質的邊界和不滿足性質的邊界都能找到),邊界就是我們要的答案。

假設某一性質可以將乙個l到r的區間一分為二,即如圖所示的紅色區間和綠色區間。兩個箭頭分別為兩個區間的邊界,即為我們所要求的答案。

二分首先應該找到區間中點:

int mid =

(l+r+1)

>>

1

或者是:

int mid =

(l+r)

>>

1

兩種找中點的**對應兩種情況。

然後判斷mid是否滿足紅色區間的性質或者綠色區間的性質:

if

(check

(mid)

)//check函式就是紅色區間的性質或者綠色區間的性質

第一種情況:假設答案滿足紅色區間,不滿足綠色區間①如果check(mid)為true,則mid在紅色區間上,我們所要求的答案就在[mid,r]這個區間裡,更新區間的方式為l=mid

②如果check(mid)為false,則mid在綠色區間上,我們要求的答案就在[l,mid-1]這個區間裡,更新區間的方式為r=mid-1。注意:這裡由於mid在綠色區間上,而我們的答案要滿足紅色區間的性質,所以mid已經不可能是答案,所以答案的區間是[l,mid-1]。

第二種情況:假設答案滿足綠色區間,不滿足紅色區間

①如果check(mid)為true,則mid在綠色區間上,我們所要求的答案就在[l,mid]這個區間裡,更新區間的方式為r=mid。

②如果check(mid)為false,則mid在紅色區間上,我們要求的答案就在[mid+1,r]這個區間裡,更新區間的方式為l=mid+1。注意:這裡由於mid在紅色區間上,而我們的答案要滿足綠色區間的性質,所以mid已經不可能是答案,所以答案的區間是[mid+1,r]。

第一種情況的**模板:

int

bsearch_1

(int l,

int r)

else

}return l;

}

第二種情況的**模板:

int

bsearch_2

(int l,

int r)

else

}return l;

}

問題:第一種情況的mid為什麼是(l + r + 1)>> 1,而第二種情況的mid是(l + r + )>> 1?

當區間為[l,r],l=r-1時,如果mid=(l+r)>>1,則mid=(2l+1)>>1=l(下取整),在第一種情況中,如果check(mid)為true,則答案所在的區間還是[l,r],這時每次迴圈都是[l,r]就進入了死迴圈。

所以第一種情況要補上+1!

由於浮點數沒有整除問題,每次區間長度可以嚴格縮小一半,所以只有一種情況,思路和整數二分一樣,同樣是判斷答案會落在哪乙個區間,保證每次答案落在區間裡,當區間長度非常小時,就可以認為找到了答案。

浮點數二分**模板:

double

bsearch_3

(double l,

double r)

else

}return l;

}

c 二分答案 基礎應用

使得x x達到或超過n位數字的最小正整數x是多少?n 2000000000 對與這種較難求解的問題,我們很難想出較好的解決策略。但是,我們至少知道答案一定在1與2000000000之間,能否轉換二分查詢的思想,對答案進行二分查詢呢?當然是可以的,但在二分查詢中有比較,在二分答案中,我們也需要有比較,...

演算法學習 二分搜尋二分答案2

顧名思義,二分答案就是用二分查詢的思路去找答案,下面通過舉例來說明。題目 p1873 砍樹 砍下樹木的高度 h 從 0 一直到所有樹木中最高的高度 hmax 依次遞增,我們可以此為依據進行二分搜尋得出答案。includeusing namespace std long long n,m,arr 10...

基礎演算法 二分

二分模板 bool check int x 檢查x是否滿足某種性質 區間 l,r 被劃分成 l,mid 和 mid 1,r 時使用 int bsearch 1 int l,int r return l 區間 l,r 被劃分成 l,mid 1 和 mid,r 時使用 int bsearch 2 int...