跳石头

Description

一年一度的“跳石头”比赛又要开始了!

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有N块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走M块岩石(不能移走起点和终点的岩石)。

Analysis

一开始想到贪心,每次把最短的距离与相邻最短的距离合并,其实类似于合并石子,是可以证明此贪心法则错误的。

既然要使最小值最大,很明显的二分答案。每次处理出一个mid,如果在此mid限制下跳到终点掠过的石头数小于M则增大mid,反之减小。可行性判断时直接模拟,跳到大于mid的最近的石头,计算途中不得不掠过的即可。

Code

#include <bits/stdc++.h>
#define ll long long

using namespace std;

int n,m;
ll l,d[50010],ans; 

int search(ll l,ll r)
{
	if(l==r-1)
		return l;
	ll mid=(l+r)/2;
	int sub=0,cnt=-1;
	while(sub<n)
	{
		bool flag=false;
		for(int i=sub+1;i<=n;i++)
			if(d[i]-d[sub]>=mid)
			{
				cnt++;
				sub=i;
				flag=true;
				break;
			}
		if(flag==false)
			return search(l,mid);
	}
	if(n-1-cnt>m)return search(l,mid);
	else return search(mid,r);
}

int main()
{
	freopen("stone.in","r",stdin);
	freopen("stone.out","w",stdout);
	cin>>l>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>d[i];
	d[++n]=l;
	ans=search(0,l+1);
	cout<<ans<<endl;
	return 0;
}

posted @ 2018-08-17 11:30  Srzer  阅读(180)  评论(0编辑  收藏  举报