1. 程式人生 > >用二分枚舉答案題

用二分枚舉答案題

pri 復雜 ont 二分 n) lan get log href

以二分算法枚舉答案的方法非常高效,枚舉所需的時間復雜度只需O(logN)

設x為答案,check(x)只有真假兩種取值。

能夠使用二分枚舉算法的條件:

存在一個X,當x小於X時和x大於X時,check(x)真假值不一樣。

二分枚舉即能夠找出真假之間的邊界,這個就是所求在滿足題意下的最值了。

如果x是浮點數,那麽邊界的取值註意精度即可。

const double eps=1e-7;
while(l+eps<r)
{	mid=(l+r)/2;
	if(check(mid))	l=mid;
	else r=mid;
}

如果x是整數,那麽註意所求,是真值區的最大值還是最小值,見例題。

例題:https://www.nowcoder.com/acm/contest/52/E

AC代碼:

#include<iostream>
#include<algorithm>
using namespace std;
int c[10005],v[10005];
long long p[10005];
int n,k;

bool check(int x)
{	for(int i=0;i<n;i++)
		p[i]=v[i]-x*c[i];
	sort(p,p+n);
	long long sum=0;
	for(int i=n-1;i>=n-k;i--)
		sum+=p[i];
	return sum>=0;
}

int main()
{
   int T;
   scanf("%d",&T);
   while(T--)
   {
   		
		 scanf("%d%d",&n,&k); 
		for(int i=0;i<n;i++)
			scanf("%d%d",&c[i],&v[i]);
		int l=0,r=100000,mid,res;
		while(l<=r)
		{	mid=(l+r)/2;
			if(check(mid))
			{	res=mid;
				l=mid+1;
				
			}
			else r=mid-1;
			
		}
		printf("%d\n",res);	
   } 
    return 0;
}

  

用二分枚舉答案題