1. 程式人生 > >二分法求解最大最小值模板

二分法求解最大最小值模板

這類問題有個明顯的特徵:使最小值最大或者使最大值最小。這個時候大概步驟就是先對讀進來的資料進行排序(因為二分查詢是在有序的資料上進行的)然後執行二分。其中二分裡的check函式是最關鍵的部分,例如第一題中我們就是二分答案,然後在check中貪心的來安排牛的位置,看是否能夠滿足答案。而第二題也是二分答案,check中按我們求出的答案把不滿足答案的石頭撤掉,看是否能夠滿足答案。這就是check的大概思路:即檢查是否能夠滿足答案。

  二分中還有一個重要的細節:求最大值的最小值時mid=(l+r)/2,l=mid+1,r=mid;而查詢最小值的最大值時mid=(l+r+1)/2,l=mid,r=mid-1。不然程式會陷入死迴圈,或者得不到正確答案。

  最後一點就是實數二分的時候因為精度需要常常我們會讓程式一直進行計算,然而由於計算時的精度誤差,常常也會使程式效率低下或者死迴圈。一般來講我們這時可以限制二分次數,一般60-70次即可滿足精度需要,這樣可以提高程式效率,避免TLE的情況出現。

  最最後一點,這類問題資料量一般都非常大,記得用scanf讀入,第一題我就因為用cin而TLE了,改成scanf之後馬上就過了。。。。。

     二分法求最大最小值模板:

#include<iostream>
using namespace std;
bool judge(int mid)//判斷是否符合條件
{
	for(迴圈)
	{
		求解計數結果num,++num; 
	} 
	if(num與題目邊界條件)
		return true;
	else
		return false; 
} 
int main()
{
	int l, r, ans = 0;
	l = ;//l和r的具體值要看題目是需要列舉的什麼 
	r = ;
	while(l <= r)
	{
		int mid = (l+r)/2;//mid = l + (r-l)/2
		if(judge(mid))
		{
			ans = mid;
			l = mid + 1;//也有可能不是1,可能是一個小數,要看具體的間距 
		}
		else
		 	r = mid -1;
	 } 
	 cout << ans << endl;
	 return 0; 
}

具體樣例參考: