對於二分的理解

2022-05-21 18:18:07 字數 1887 閱讀 3664

看了曦行夜落-**二分的邊界問題後深有感觸,特此寫下此篇部落格以作梳理。

二分是一種求取極值的演算法,通常是已知所求答案的範圍,然後根據一系列約束條件對其進行控制使得到的答案最優。二分答案需要滿足單調性,舉個例子來看,我們要完求完成任務的最小代價(範圍為1到100),我們考慮中間值50:

如果以50的代價可以完成任務,那麼,我們以51~100的代價顯然也可以完成任務。

如果以50的代價不能完成任務,那麼,我們以0~50的代價就都不能完成任務。

正是因為這種單調性,才使得二分可以在log2n的時間內完成查詢工作。

我們接著考慮上面的例子,我們可以發現:

如果以50的代價可以完成任務,那麼,我們以51~100的代價顯然也可以完成任務。則,我們需要在0~50中去尋找更優的滿足條件的解。

如果以50的代價不能完成任務,那麼,我們以0~50的代價就都不能完成任務。則,我們只能通過去犧牲資料,在51~100中去需找滿足條件的解。

這就是二分的進行機制,由此,我們可以發現,二分中真正重要的地方是中間條件的取值。

二分的中間值是二分過程中最容易出鍋的地方, 對於是應該取mid + 1還是mid - 1又或是mid常常讓人混亂,這裡我們對其進行一定的梳理。

二分中的主要思想有以下三種:

l 和 r 所代表的」成本值」均可行(即當前討論的區間為[ l, r]),且存在乙個最優解ans。

l 和 r 所代表的「成本值」均可行,最後答案是 l 和 r。

l 和 r 所代表的「成本值」只有 l 可行而 r 不可行(即當前討論的區間是[l, r ) ),最終的答案是 l。

我們對前兩種演算法進行模板歸納

思想1:儲存答案

for (;l<=r;)

else l=mid+1;}

printf("%d

",ans);

結束條件是l > r 時停止迴圈,此時答案記錄為ans。(依舊以上面舉到的例子求大於條件的最小值)

對於每次迴圈中的mid,都把當前的區間分為了三部分[l , mid - 1] , mid, [ mid + 1, r],這三部分中,我們根據mid處的值將問題分為兩類。

當mid滿足條件的時候,我們就把mid當作是的當前的最優解,然後去考慮[l, mid - 1]中有沒有可以重新整理當前最優解的更優解。

當mid不滿足條件的時候,我們就考慮[mid + 1, r]中有沒有可以滿足條件的解。

求大於的最小值則正好相反。

思想2:不儲存答案

while (lprintf("%d

",l);

結束條件是 (l == r),此時l 和 r 相同且都是最優解。(依舊以上面的例子求大於條件的最小值)

對於每次迴圈中的mid,都把當前的區間分為了兩部分[l, mid], [mid + 1, r],這兩部分中我們根據mid的值將問題分為兩類。

當mid滿足條件的時候,我們把mid看作是乙個可行解,根據二分的單調性我們可以知道[mid + 1, r]一定都滿足條件且沒有mid更優,所以我們可以得到更優的解一定是存在於[l, mid]中的。為什麼要包括mid呢?我們可以這樣來看,我們假設當mid就是滿足條件的最優解而且這個區間中數的個數不只乙個,如果我們只考慮[l, mid - 1]的話,就會因為漏解而使得最終答案錯誤。

當mid不滿足條件的時候,根據單調性[l, mid]一定都不能滿足條件,所以我們只需要在[mid + 1, r]中尋找滿足條件的解即可。

反過來,如果我們求的是小於條件的最大值時,對於每次迴圈中的mid, 都把當前區間分為了兩部分[l, mid - 1],[mid, r],兩部分。

二分查詢就是最經典的二分答案,我們對於乙個有序序列,記錄查詢值為key的數, 而對於乙個為key的數,我們既可以把他看作是滿足大於條件的最小值,也可以看作是滿足小於條件的最大值。

二分查詢演算法的理解

在做lis的o nlgn 演算法時,用到了二分查詢演算法。對於其中的一些條件,例如 l二分查詢因為有幾個限制,其中乙個便是 單調序列 這個要求,所以可能出現 2 3 4 4 4 5 6這樣的陣列,那麼返回第乙個出現的位置便是 i 3時。i0 1234 56a i 23 4445 6while lef...

非常簡單地理解帶權二分(wqs二分)

非常感性簡單地理解帶權二分 又名 wqs 二分 儘管不是很嚴謹,如有錯誤請指出 large natural gosha is hunting 原題鏈結 更好閱讀體驗 設我們有 a 個紅球和 b 個藍球,用紅球抓 i 號胖可丁的概率是 a i 用藍球抓 i 號胖可丁的概率是 b i 首先我們有乙個暴力...

二分的模板(花式二分)

對於不下降序列a,n為序列a元素的個數,key為關鍵字 1.求最小的i,使得a i key,若不存在,則返回 1 int binary search 1 inta,intn int key if a r key returnr return 1 2.求最大的i,使得a i key,若不存在,則返回 ...