和3273类似,二分穷举。
下界为最短跳跃距离,上界为最长跳跃距离。
二分搜索,以其中值为答案,反推出所移除的石头数为k,若k<M则说明跳跃距离太小以至于移除石头数不够M。
反之k>M说明跳跃距离太大移除了过多的石头。以此收缩上下界。
若k==M,则此时mid可能是解也可能不是,需要继续上移下界,看有无更优解。
最终得到的解可能是正解,也可能是正解+1。
if(valid(low))
cout<<low<<endl;
else
cout<<low-1<<endl;
所以最后需要判断一下是否此解移除正好M个石头。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
int L,N,M;
int low,high;
int dist[50002];
bool valid(int dis){
int count = 0;
int sum = 0;
for(int i=1;i<=N;++i){
sum += dist[i]-dist[i-1];
if( sum < dis){
++count;
}
else
sum = 0;
}
return count<=M;
}
void process(){
while(low<high){
int mid = (low+high)/2;
if(valid(mid))
low = mid+1;
else
high = mid-1;
}
if(valid(low))
cout<<low<<endl;
else
cout<<low-1<<endl;
}
int main(){
cin>>L>>N>>M;
low = L;
high = L;
for(int i=1;i<=N;++i)
cin>>dist[i];
dist[N+1] = L;
sort(dist,dist+N+2);
for(int i=1;i<=N-1;++i)
low = min(low,dist[i]-dist[i-1]);
process();
return 0;
}