二分搜尋的其他用法

2021-08-21 19:14:49 字數 2581 閱讀 3422

二分搜尋,最常見的是在有序陣列中最快地查詢某個特定的值,但是二分搜尋也有一些別的用處,利用二分搜尋的特性,當某個集合按某個特性「有序」時,我們就可以很好地利用二分搜尋來找到所需的元素,而不是僅僅侷限在最初所學的用途上。

在討論別的用途前,先考慮下最基礎的用法,也就是如何在乙個數列中找到符合條件的值。

來看一道例題:

1、已知有n個正整數a0, a1, a2, a3,...,和乙個正整數k,試問滿足ai>k的最小的ai是多少,不存在時輸出-1;

n

00樣例輸入:( 第一行為n k)

7      12

23    1    6    11   12   8    15

樣例輸出:

思路:利用基本的二分搜尋就可以解決。

sort(a, a+n); //公升序排序

int l=-1, r=n; //左開區間,右閉區間

while (r-l>1)

if (a[l]>k)

cout上面這種演算法就是二分搜尋演算法,stl提供了lower_bound函式實現二分搜尋

根據二分搜尋的特性,我們可以得到乙個結論,二分查詢可以在有序集合中快速找到所要的乙個元素,重點在有序上,對於上面的用法,我們二分的依據是「大於」,也就是說對於乙個符合「大於」條件的元素,其右側所有元素都必定符合這個條件,相反,不符合「大於」條件的元素的左側所有元素都不會符合這個條件,這就是一種有序。

如果我們將這個判斷條件稍微複雜化,就可以得到另一種用途,先看道例題:

poj 2456     題目大意是:

農夫john有一間n(2 <= n <= 100,000) 個畜欄的牛舍,這些畜欄排在一條直線上,它們的位置是x1,...,xn (0 <= xi <= 1,000,000,000)。他的c(2 <= c <= n)頭牛對牛舍很不滿意,所以john為了防止牛相互打架,所以想給牛分配這些畜欄,一頭牛佔乙個畜欄,希望最大化最近兩頭牛之間的距離。所以可以得到的最大的最近兩頭牛的距離是多少?

輸入樣例:

n=  5     c= 3

xi= 1    2    8    4    9

輸出樣例:

思路:

(1)可以發現,如果我們將最近兩頭牛之間的距離視為乙個數列,既這個數列為 ,然後分析二分查詢所需的條件。可以發現如果可以得到某個距離d,既至少有一種分配方法可以使最近距離大於等於d。那麼在上面那個數列中,d左側所有值都是成立的;相反,如何d無法被得到,那麼d右側所有值都不會成立。

(2)判斷距離d是否可以實現,只需從左向右,距離大於等於d時的畜欄放一頭牛,既貪心演算法就可以實現。

所以,對答案進行二分,也就是對1~1 000 000 000所有整數進行二分,每次取mid值進行判斷,最終剩下的乙個值就是所需的最大的最近距離。

二分的判斷條件:  check(d) :  可以按某種方式分配畜欄,使相鄰兩頭牛最近距離為d,並返回true。

**如下:

#include#include#include#define max 1e9

using namespace std;

int n, c;

int x[100002];

bool check(int d)

}if (temp>0)

return false;

return true;

}int main()

cout有時需要二分的元素或者集合比較難以發現,比如下面這個最大化平均值的問題:

有n(1<=n<=10,000)個物品的重量和價值分別是wi和vi(1<=wi,vi<=1,000,000)。從中選出k(1<=k<=n)個物品使得單位重量的價值最大,輸出單位重量的價值。

思路:顯然,如果將每個物品的單位價值分別計算出來,再排序進行從大到小選取,結果是不正確的。但這個問題可以用二分查詢解決,於是主要問題就是如何設定需要二分的元素的集合和二分的條件。

(1)首先像上一道題一樣,對答案進行二分,二分的區域就是最終結果的取值範圍。

(2)繼續按套路,很容易得到二分條件:

check(x):可以選擇k個物品使得單位重量的價值不小於x

該check(x)函式滿足如下這個條件,對k個物品的集合進行討論

可以發現這個不等式很難在盡量少的時間內計算出來,因此可以將它化簡一下

因此,我們只需要把每個物品的

最後,在進行二分的時候,因為這個問題的結果是double型別的,而為了提高結果的準確性,可以將二分的迴圈條件改為迴圈次數,而不是上下界的關係。

對答案進行二分 + 實現二分條件

Python 中 else語句的其他用法

else 子句不僅能在 if 語句中使用,還能在 for while 和 try 語句中使用。for i in range 5 print for else print end for i 0 while i 5 print while i 1 else print end while try pr...

Java 二分搜尋 二分查詢

對陣列元素進行逐個查詢顯然是費時費力的工作,我們可以使用一些方法快速地搜尋出陣列中元素的指定位置.接下來我們介紹一種方法 二分搜尋法 二分搜尋法充分利用了元素間的次序關係.基本思想 將n元素分成個數大致相同的涼拌,取arr n 2 與欲查詢的x做比較,如果 下面將採用兩種方式 遞迴 非遞迴 來展示二...

二分(二分答案 二分搜尋)與單調性

經典二分搜尋是二分空間範圍。二分答案又叫二分猜值,是二分解的值空間。其實可以統一,普通的二分搜尋也是二分答案值域 下標空間,也是猜值。二分必須滿足單調性,最直觀的,二分搜尋只能在有序陣列上進行。單調性體現在,下標和元素值是單調的,也就是 if j i 有 a j a i 一般二分答案解決的問題是最優...