poj3258 二分及一些思考

2021-06-05 00:48:43 字數 1928 閱讀 7557

題意:牛要到河對岸,在與河岸垂直的一條線上,河中有n塊石頭,給定河岸寬度l,以及每一塊石頭離牛所在河岸的距離,

現在去掉m塊石頭,要求去掉m塊石頭後,剩下的石頭之間以及石頭與河岸的最小距離的最大值。

用二分做,但是開始寫了三個版本的二分,全都wa。

無賴看了別人的二分,還是不理解,為什麼他們寫的就能過。

反覆思索後,終於明白了:關鍵在於題目求的是什麼。

做題思想:二分所求的最小距離的最大值mid,記錄可以去掉的石頭塊數cnt(注意:當相鄰的石頭的距離小於等於mid,就可以去掉),

若cnt > m,h = h - 1 (這裡是比較難理解的,也是我糾結挺久的地方),此時,應當回過頭來看一下題目求的是什麼:

尋找乙個長度mid,使得可以去掉m塊石頭,剩下的石頭中,石頭間的最小距離為mid

但是cnt記錄的是:相鄰距離小於等於mid的塊數,所以存在這樣的一種情況  ---- cnt記錄的所有石頭中,

有很多塊石頭間的距離是等於mid,而距離小於mid的石頭的塊數是小於等於m的,此時,若將h的值減一,

那麼h的值就變成乙個小於題目所求的答案了。

舉個例子就懂了:假設有9塊石頭,首尾的數都表示河岸。

石頭的編號                      1     2     3     4     5        6         7     8      9  

石頭到河岸的距離     0    4     5     7     9    12      16       19   23     26     28

相鄰的距離                  4    1      2     2     3      4        3        3      3       2

假設l = 1,h = 5, m = 4    則mid = 3, 此時去掉的石頭的編號為:2,3,5,7,9  cnt = 5

按照程式,h = h - 1 = 4,此時mid = 2,去掉的石頭的編號就為:2,4,9     cnt = 3(cnt當然也有可能cnt == m,總之就是cnt > m不成立了)

也就是說,之後求得的cnt <= m恆成立, 即題目的答案不在  l 和 h 之間了(這點

之前是讓我很費解的地方),更準確地說,答案就是執行這次h-1之前的h值。

若cnt <= m,則l = l + 1,討論一下:若cnt < m,明顯當前的mid小了,l = l + 1;若cnt == m,則去掉cnt塊石頭後,

剩下的石頭的最小值必然是大於mid的,所以進行操作l = l + 1。

然後解決上面遇到的問題,因為h已經小於答案了,而答案就是h+1,之後繼續二分cnt <= m恆成立,

l 不斷自增,直到跳出迴圈,因為答案為h+1,我們返回 l 的值,那麼while的判斷條件就是 l <= h,

當 l 自增到 h + 1時就跳出迴圈,l == h + 1,正好就是答案。

寫了這麼多,就是分析了一下二分演算法執行的過程,因為以前用的二分while判斷條件都是 l < h,看樣子以後做二分得多注意了,

稍不注意就會有很多致命的小bug,一定要將對 l 和 h 的操作以及 while的判斷條件結合起來考慮,要對二分演算法進行靈活的變化,

沒有一成不變的模版,具體問題具體分析。

**:

#include #include #include using namespace std;

int l, n, m;

int d[50005];

bool cmp(int a, int b)

int bsearch(int l, int h, int k)

if (cnt > k) h = m - 1;

else l = m + 1;

}return l;

}int main()

POJ 3258 二分 貪心

poj 3258 二分 貪心 一條線段兩個端點之間的距離是l,兩端點之間分布著n個點,這n個點把線段分成了n 1份,現在讓你最多去掉 第一次讀錯題想了很久不知道怎麼做,remove是去掉不是移動,m個點,問n 1份線段最小值的最大值是多少 1 l 109,0 m n 50000 分析類似poj 32...

POJ 3258青蛙過河 二分答案

description 有一條寬度為l 1 l 1,000,000 的河。河中間有n 0 n 20000 塊石頭,青蛙從河西岸經過這n個石塊後,順利跳到了河的東岸。設河中間每個石塊距離西岸的距離為di 其中di大於0小於l 注意 di是距離起始河岸的距離。小明閒著沒事,想移掉河中間的m 0 m n ...

poj 3258 二分最小值最大

題意 有一些石頭排成一條線,第乙個和最後乙個不能去掉。其餘的共可以去掉m塊,要使去掉後石頭間距的最小值最大。解析 二分石頭,最小值最大。include include include include include include include include include include in...