二分
二分,他可以應用的範圍特別廣,即使是你想不到的地方他也可以二分。
例如:Acwing790數的三次方根這題可以直接二分題目所要求的答案,透過不斷逼近三次方後的結果來二分; Acwing5407.管道,這題裡可以直接二分時間,然後合併區間檢視是否滿足; Acwing730.機器人跳躍問題可以直接對其能量進行二分,然後檢查是否會虧損能量。
所以二分到底什麼時候能用?核心在於答案是否有單調性,也就是說,答案會因為資料的增長而單向前進(上升或下降),由此我們才能進行二分。
二分的模板非常非常的簡單,取中值,判斷中值情況再調整左右區間。
while(條件)
{
int mid = (l+r)/2;
if(條件)
l = mid;//左區間不滿足條件,將左邊界移到中間
else
r = mid;//右區間不滿足條件,將右邊界移到中間
}
二分的複雜度大約就是\(O(logn)\),所以資料集一大起來一眼不能暴力的時候,就可以先看看題目是否滿足二分了。
一定要注意的是,二分不一定能用在有多個最優解的情況裡,二分很有可能只尋找到其中一個最優解,但是如果設定不同的條件二分也確實可以找到更多的解。例如藍橋杯的冶煉金屬一眼就可以認出來,第一次二分找到最小解,第二次二分找到最大解即可。