用二分枚举答案题

以二分算法枚举答案的方法非常高效,枚举所需的时间复杂度只需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
",res);	
   } 
    return 0;
}

  

原文地址:https://www.cnblogs.com/lnu161403214/p/8074764.html