永遠不會的二分(二分做不對)

2021-10-11 07:22:08 字數 3252 閱讀 6685

二分這個知識點,我好像在高中就有在數學課本中接觸,到了程式設計上才知道,二分是真的難。

二分殺我!!!

首先呢,說一說我對做二分題的理解

二分題先要理解題意然後去套模板就可以了,去理解是找》=x的最小值還是<=x的最大值,下面是兩個模板。

>=x的最小值模板

while

(l < r)

<=x的最大值模板

while

(l < r)

以上的兩個模板,在我做題的過程中是沒有問題的(可能因為我比較菜),不過既然這個模板可以存下來,就證明它是經過很多人試驗並補全的。

當然我們不能一味的死套模板,需要根據實際情況加以變通(目前我還不會,沒有遇到)

小數二分我認為較為簡單,模板如下

while

(r - l > eps)

個人認為,無論是整數二分還是小數二分,關鍵在於用對模板和寫好check函式,當然l,r的值也需要注意(後邊有例題會專門提到)

題目這項比賽將在一條筆直的河道中進行,河道中分布著一些巨大岩石。組委會已經選擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 n塊岩石(不含起點和終點的岩石)。在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達終點。

為了提高比賽難度,組委會計畫移走一些岩石,使得選手們在比賽過程中的最短跳躍距離盡可能長。由於預算限制,組委會至多從起點和終點之間移走 m 塊岩石(不能移走起點和終點的岩石)。

輸入第一行包含三個整數 l,n,ml,n,m,分別表示起點到終點的距離,起點和終點之間的岩石數,以及組委會至多移走的岩石數。保證 l≥1 且 n≥m≥0。

接下來 n 行,每行乙個整數,第 i 行的整數 di( 0 < di 輸出

乙個整數,即最短跳躍距離的最大值

輸入例子

25 5 2 211

1417

21輸出

4首先我們理解題意,要找跳躍距離的最大值

所以,我們要使用<=x的模板

int l =

0,r =l;

//左邊界l為0,右邊界r為起點石頭到終點石頭的距離

while

(l < r)

模板用對後,我們就需要根據題意去寫check函式

bool check

(int x)

if(count <= m)

return

true

;//如果需要移走的石頭數<=規定的返回true

else

return

false

;//否則返回false

}

整體**如下

#include 

#include

using namespace std;

const int n

=500010

; int n,m;

//n為起點到終點的岩石數,m為組委會 至 多 移走的岩石數。

int l

,a[n];

bool check

(int x)

if(count <= m)

return

true

;else

return

false;}

int main()

printf

("%d"

,l);

return0;

}

其實按照這個思路來 跳石頭還蠻簡單的哇

接下來看乙個需要對l和r的值特別注意的題。

題目對於給定的乙個長度為n的正整數數列a1∼an ,現要將其分成 m(m≤n)段,並要求每段連續,且每段和的最大值最小。

關於最大值最小:

例如一數列4 2 4 5 1 要分成 3 段。

將其如下分段:

[4 2][4 5][1]

第一段和為 6,第 2 段和為 9,第 3 段和為 1,和最大值為 9。

將其如下分段:

[4][2 4][5 1]

第一段和為 4,第 2 段和為 6,第 3 段和為 6,和最大值為 6。

並且無論如何分段,最大值不會小於 6。

所以可以得到要將數列4 2 4 5 1 要分成 3 段,每段和的最大值最小為 6。

輸入第 1 行包含兩個正整數 n,m。

第 2行包含 n 個空格隔開的非負整數 a_i,含義如題目所述。

輸出乙個正整數,即每段和最大值最小為多少。

輸入例子

5 34 2 4 5 1輸出6

同樣先理解題意,找最大值最小為多少我們就得用》=x的模板

while

(l < r)

但是我們要注意l,r的取值

for

(int i =

0;i < n;i ++

)

我們可以根據題意知道二分的範圍,左邊界應該不小於數列分段單個最大值,右邊界不大於總和。

當l取0的時候是有乙個測試點會wa的,我也不知道為啥,根據討論區大佬所說,如果不取最大的那個的話在判斷函式裡就要考慮完不成的情況,如果取最大就不用考慮如果不取最大值check函式那裡可能要加一些判斷條件

整體**如下(不做過多解釋,理解就可)

#include 

#include

using namespace std;

const int n

=1e5+10

;int n,m;

int a[n]

;int l,r;

bool check

(int x)

return cnt < m;

}int main()

//r = 1000000000;

while

(l < r)

printf

("%d"

,l);

return0;

}

小數二分就不再過多提及,主要再check函式,可以多加摸索取找到解題思路(不是因為我不熟才不提及的)

總之呢,做二分題重點還在理解題意、找對模板、寫好check函式

(以上為個人理解,我還是個程式設計菜鳥,嘻嘻~)

1128 二分 二分查詢

時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述nettle最近在玩 艦 因此nettle收集了很多很多的船 這裡我們假設nettle氪了很多金,開了無數個船位 去除掉重複的船之後,還剩下n 1 n 1,000,000 種不同的船。每一艘船有乙個稀有值,任意兩艘船的稀有...

二分的模板(花式二分)

對於不下降序列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,若不存在,則返回 ...

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

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