弄了一上午二分答案,終於弄明白了—— 一點點
第一點,在c++中,因為做除法是向下取整的,所以為了讓每一次計算的mid在所選區間內,一定要將左區間閉上。
我們為什麼要做二分優化呢?第一點,我們要的解答是有序的。第二點,當然是省時間了。《程式設計挑戰》中說,進行100次二分驗證,解的誤差範圍可以在10的-30次方左右。非常nice。
那麼是什麼讓我這麼頭痛呢?那就是整數的二分。
用兩道例題來說一下。
第一道,poj3104晾衣服。
#include
#include
#include
#include
using namespace std;
long long n,k,l,r;
long long c[100100];
bool solve(int day)
printf("%lld\n",r); } return 0; }
思路很簡單,二分晾衣服的時間,每次檢驗,對於衣服i,它含有c[i]的水,那麼讓它晾乾,如果它的水分<=day(即假設的總用時),那麼就不需要熨燙。如果大於它,就需要滿足以下關係式:
設它最少需要熨燙n次,那麼有:
c[i]-k*n+n<=day
也就是求滿足這個不等式的最小正整數。然而難點不在這裡。
我們看主函式。如果我們的mid可以,就說明範圍應該向左挪。那麼細節來了:l,r,mid以及輸出怎樣來考慮?
對於乙個區間[a,b),如果它的mid可以,那麼接下來有兩種情況,
1:mid就是最優解。
2:最優解在mid的左邊。
所以我讓r=mid,這樣如果mid是最優解,輸出r就是了。如果不是,那麼就接著挪。
如果mid不可以呢?那麼就讓區間向右挪,由於區間左邊是閉的,就不需要保留了,l=mid+1就可以了,而r還是前一次可行解
這樣,最後會達到什麼情況呢?
[a,a+1),根據前面的分析,a+1肯定是乙個可行解。這時,區間的mid就是a,
如果a可行,r=a,此時區間裡沒有數了,a就是最優解,此時r=a,輸出r就可以了。
如果a不可行,那麼l=a+1,區間裡沒有數了,a+1就是可行解,而r一直就是可行解,輸出r就可以了。
所以這是思考的精髓,就是讓r始終是接近最優解的可行解。而對最後區間的分析,表明迴圈的要求是r-l>0
針對本題,它的坑點是k=1要單獨判斷,因為上面的不等式,解出n之後,分母是k-1!!!!!!!!!!!!!!!!!!
還有,要用long long ,因為上式中10^9的級別的數一乘會溢位int
這道題是最小化最大值,下面看一下最大化最小值。
poj3258奶牛跳石頭兼noip2015day2第一題,我居然一開始要用堆做,然而考完了也沒反應過來是不對的。然後就跪了。
#include
#include
#include
using namespace std;
int l,n,m;
int stone[50010];
bool solve(int s)
else
}if(stone[n+1]-stone[last]>=s&&count<=m) return true;
else return false;
}int main()
printf("%d",l-1);
}
判斷的地方,就要注意終點石頭和最後剩下的那塊之間的距離也要對就行了。
重點還是說二分。
這題我們怎樣使用左閉右開區間呢?
總思路:用l控制接近最優解的可行解。
對於區間[l,r)
如果它的mid不可以,那麼r=mid,那端不要了,不傷大雅。
如果它的mid可以,那麼l=mid,也可以l=mid+1;
如果我選擇了l=mid,那麼最後是什麼情況呢?
不太好想。假設最後是[l,l+2),它的mid一定是l+1。如果l+1可行,那麼l=l+1,形成區間[l+1,l+2),l+2不行,那麼l+1就是最優解。如果l+1不可行,那麼r=l+1,l就是最優解。所以這種方法的迴圈判定就是r-l>1
如果我選擇l=mid+1呢,假設最後是[l,l+1),l-1是那個最接近最優解的可行解,l是這個區間的mid,如果mid可行,那麼l=l+1,區間裡沒有數了,現在的l就是最優解。說的有點迷糊。對於區間[5,6),4就是它最接近最優解的可行解,那麼如果5可以,那麼形成區間[6,6},這個區間的l-1,也就是5,就是我們要的答案。如果mid不行,r=5,形成區間[5,5),它的l-1,即4就是最優解。而我附的**就是按第二種思路寫的。
而第一題之所以沒有r=mid-1的寫法,因為右側是開的,左+1,右-1,很容易出現[3,1)的情況,就難以控制了,我一測是wa,不好。
所以,這種二分答案的思路,大同小異,最主要的掌握核心:控制哪個是最接近最優解的可行解,然後就需要靈活處理,看最後的情況。這樣,二分答案就沒什麼可怕的了,來幾道,做幾道。
祝大家學習進步,願oi永葆青春。
二分查詢與二分答案
主要用於在乙個單調的函式中查詢某值 連續函式的情況 若當前查詢的區間是 l,r 查詢的值是 y 函式單增 設 mid l r 2 若 f mid y 則 l mid,否則 r mid 直至 r l eps 當前查詢的區間是 l,r 查詢的值是 y 函式單增 設 mid l r 2 若 f mid y...
二分查詢和二分答案
1.解釋 優點 查詢速度快。缺點 待查表為有序表。4.時間複雜度 o log n 5.示例 p2249查詢 include include using namespace std long long n,m,a 1000005 b 100005 l,r,mid,cnt,x intmain for i...
二分與二分答案學習
判斷left,mid,right的符號進行區間的精確。如下為遞迴二分求零點的操作 double find zero point double left,double right,double precesion double mid right left 2 if f mid 0 if f mid ...