• Luogu P2678跳石头


    Description:

    一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石)。

    Analysis:

    一般最小值最大的问题都是二分答案,初始时区间答案可能在的区间[1,L + 1],不断二分,判断中间点 mid 是否可行。至于判断,因为答案是最短的距离,所以要使所有点之间的距离大于等于 mid,从第一个点到第 n+1个点扫一遍,如果一个点到上一个点之间的距离小于mid,那么就将该点删去,最后看删去的点是否大于m。如果mid可行,那么可能会有更优的解,也就是说mid可以更大,将左端点右移;否则,删去的点太多,mid不是合法解,将右端点左移。

    Code

    #include<cstdio>
    #define N 50005
    using namespace std;
    int d[N],L,n,m;
    bool Check(int x)
    {
    	int last = 0,cnt = 0;
    	for(int i = 1;i <= n + 1;++i){
    		//each distance >= x
    		if(d[i] - d[last] < x) ++cnt;
    		else last = i;
    	}
    	if(cnt > m) return 0;
    	return 1;
    }
    void solve()
    {
    	int lb = 0,ub = L + 1;
    	while(lb + 1 < ub){
    		int mid = (lb + ub)/2;
    		//mid could be larger 
    		if(Check(mid)) lb = mid;
    		else ub = mid;
    	}
    	printf("%d
    ",lb);
    }
    int main(){
    	scanf("%d %d %d",&L,&n,&m);
    	for(int i = 1;i <= n;++i){
    		scanf("%d",&d[i]);
    	}
    	d[n + 1] = L;//Attention
    	solve();
    	return 0;
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    Java日志第8天 2020.7.13
    Java日志第7天 2020.7.12
    Java日志第6天 2020.7.11
    Java日志第5天 2020.7.10
    Java日志第4天 2020.7.9
    Java日志第3天 2020.7.8
    设计模式_23种设计模式_目录
    ICacheEntry中SlidingExpiration与AbsoluteExpirationRelativeToNow的区别
    MySql中的replace into
    结巴分词
  • 原文地址:https://www.cnblogs.com/Zforw/p/10698449.html
Copyright © 2020-2023  润新知