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;
}