二分总结 挑战

挑战上面讲的很全了,自己实现了一遍,在做个总结。

一些注意:

  1. 最后实在不知道输出mid left 还是right,就把mid mid+1 mid-1根据特定的顺序都判断一遍就不会出错。

一:二分查找值

普通的二分。

二:假定一个解并判断是否可行。

1:切小木棍

//最经典的就是从n个小木棍里面切除k个最长的,求出最长的长度。
//http://222.22.65.164/problem.php?id=4245题目链接
//有两种写法,一种是取mid100次,另一种是卡r-l>=1e9等,但是不要卡的太小,会陷入死循环
//输出一定是用r而不是mid因为r一定>=mid,向下取整的时候,r一定可以,但是mid就不一定了。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4;
double len[maxn];
int n,k;
bool isleft(double mid)
{
	int ans=0;
	for(int i=1;i<=n&&len[i]>=mid;i++)
		ans+=len[i]/mid;
	if(ans>=k) return false;
	else return true;	
}

int main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)	
		scanf("%lf",&len[i]);
	sort(len+1,len+n+1,greater<double>());
	double l=0,r=2*len[1],mid;
	for(int i=1;i<100;i++){
		mid=(l+r)/(double)2;
		if(isleft(mid)) r=mid;
		else l=mid;
	}
	printf("%.2lf",floor(r*100)/(double)100);
//	do{
//		mid=(l+r)/(double)2;		
//		if(isleft(mid)) r=mid;
//		else l=mid;
//	}while(r-l>1e-9);
//	printf("%.2lf",floor(r*100)/(double)100);
	return 0;
}

2: 

三:最小值的最大值(洛谷跳石子问题)

https://www.luogu.org/problemnew/show/P2678

#include <bits/stdc++.h>
using namespace std;
const int maxn=50005;
int L,N,M;
int pos[maxn];
bool judge(int len)
{
	int ans=0;
	int beg=0;
	for(int i=2;i<=N+1;i++){
		while(pos[i]<beg+len&&i<=N+1){
			ans++;
			i++;
		}
		beg=pos[i];
		if(ans>M) break;
	} 
	if(ans>M) return true;
	else return false;
}

int main()
{
	cin>>L>>N>>M;
	for(int i=2;i<=N+1;i++)
		scanf("%d",&pos[i]);
	pos[1]=0,pos[N+2]=L;
	int l=0,r=L,mid;
	while(l<r)
	{	
		mid=(l+r)/2;
		if(judge(mid)) r=mid-1;
		else l=mid+1;
	} 
	int ans;//最后一步搞得有些流氓了。。。但是在拿不准选哪个。
	if(!judge(mid+1))  ans=mid+1;
	else if((!judge(mid))) ans=mid;
	else ans=mid-1;
	printf("%d",ans);
	return 0;
}

四:求平均值的最大值

这一类的问题很容易被当成贪心。

有n个重wi 价值为vi的物品,从中选取k个,让他们总单位体积的价值最大。这可不是贪心啊

 

猜你喜欢

转载自blog.csdn.net/qq_41755258/article/details/84795626