二分這個知識點,我好像在高中就有在數學課本中接觸,到了程式設計上才知道,二分是真的難。
二分殺我!!!
首先呢,說一說我對做二分題的理解
二分題先要理解題意然後去套模板就可以了,去理解是找》=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 一般二分答案解決的問題是最優...