P2672跳石头

这是2015noip的一道二分答案的题目,看了题解才会,,

题目给出石头的位置并且让你踩着石头往前跳,最多删掉m个石头还可以顺利通过,求解最短跳跃距离的最大值。

那么二分什么呢:mid为跳跃的长度。那么left=0,right=l进行二分.再拿s和now分别记录当前搬走的石头数量,判断是否可以跳过去(用类似前缀和的思想)。最后当前跳跃使得搬走的石头>=m,那么则让right=mid-1,如果搬走的<=m,那么就记录下当前的mid,left=mid+1。又因为题目说的是最小距离的最大值,那么最后找到的则是最大的。

1.明确什么题目可以用二分 eg.最大的最小,k优,关键量具有单调性,最小平均路。。

2.二分什么求解什么

3.怎么来改变二分的左右端点

4.仔细读题,看好至多至少等关键字,把逻辑搞清楚

#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define maxn 600000
using namespace std;
int m,n;
int l,d;
int left,right,mid;
int a[maxn];
int s,now;
int ans=0;
int main(){
    cin>>l>>n>>m;    
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int left=0,right=l;
    while(left<=right){//二分跳跃长度 
        mid=(left+right)/2;
        now=0;//跳到第几个 
        s=0;//搬了几个石头 
        for(int i=1;i<=n;i++){
            if(a[i]-a[now]<mid){//假如跳过去了 
            s++; //搬走 
            }
            else{
                now=i;
            } 
        }
        if(s<=m){
            ans=mid;
            left=mid+1;
        }
        else right=mid-1; 
    }
    cout<<ans;
    return 0;
}

 

posted @ 2019-10-01 19:42  毛炯人  阅读(137)  评论(0编辑  收藏  举报