P2678跳石头体会 noip2015提高组

题干中说”最短距离尽可能长”,那么我们想到二分答案。

那么这道题的答案有没有一个可行的范围呢,该区间是否符合单调性呢?

来看范围:

显然对于初始的数据,从0n+1的相邻石头的距离,我们可以找到一个初始的dismin,这个可以作为left,

显然right=length(移除所有石头)。

来看单调性:

移除的石头数跟dismin肯定是递增关系的(移除石头是由于某两相邻石头间距太小)。

那么思路就是这样的:

以初始的dismin和length为答案区间的左右界,在其中二分查找一个最大的符合要求的石头最小间距

check函数即用来判断某个石头最小间距是否可行

while(lef<r)
    {
        int mid=(lef+r+1)>>1;
        if(check(mid))
           lef=mid;
        else r=mid-1;
    }

这就是二分的代码,不用left和right是因为它俩都是关键字(我也不知道是哪个库的)

每次在lef和r中间取一个数,如果符合条件,那就把lef右移,看是否有更大的解,

如果不符合条件,就把r左移,再寻找。

在以上的查找过程中,lef始终是可行的,当while循环终止时,lef就是最优解了。

需要注意的地方:为什么min=(lef+r+1)/2呢,为什么不是(lef+r)/2呢?

请读者自己思考(提示:使用后者的话会TLE)

贴上另外一种二分:

l = 1;//l和r分别代表二分的左边界和右边界
    r = d;
    while (l <= r){//非递归式二分正常向写法,可理解为一般框架
        mid = (l+r) / 2;//这再看不出是啥意思可以退群了
        if (judge(mid)){//带入judge函数判断当前解是不是可行解
            ans = mid;
            l = mid + 1;//走到这里,看来是可行解,我们尝试看看是不是有更好的可行解
        }
        else
            r = mid - 1;//噫,你找了个非法解,赶紧回到左半边看看有没有可行解
    }

以上是来自洛谷 ShawnZhou的做法。

(个人觉得第二种二分的方法好一些)

原文地址:https://www.cnblogs.com/Neptune0/p/11839942.html