zoukankan      html  css  js  c++  java
  • 二分答案&【NOIP 2015】跳石头

    二分答案估计是我应该早就学会,但拖到现在才去好好看的套路吧!

    二分答案是指在答案具有单调性的前提下,利用二分的思想枚举答案,将求解问题转化为验证结果。首先需要估计答案的上下界,然后不断取区间中点进行验证(这就要求答案的验证应当简单可行),并通过验证结果不断更新答案区间,最终得到答案。不难看出,朴素的枚举验证时间复杂度是O(n)的,而二分可以做到O(logn)。更令人欣喜的是,二分答案的问题往往有固定的问法,比如:令最大值最小(最小值最大),求满足条件的最大(小)值等。

    一道模板题练个手:https://www.luogu.org/problemnew/show/P2678


    这几乎是最简单的二分答案模板题,在明白二分答案后,是可以做到一遍AC的。题目的问法也十分模板(求最短跳跃距离的最大值),答案是单调的,拿走的石头越多,最短跳跃距离越大。我们可以估计最大的最短跳跃距离(1<=ans<=L)。然后取区间中点,进行验证。若发现某次跳跃比这个最短跳跃距离还小,那就把这块石头拿走。总共拿走的石头数不超过M,就说明区间中点符合要求,就将区间更新为右半区间(因为要求最大的最短跳跃距离);反之,就将区间设为左半区间。

     1 #include <cstdio>
     2 
     3 inline int get_num() {
     4     int num = 0;
     5     char c = getchar();
     6     while (c < '0' || c > '9') c = getchar();
     7     while (c >= '0' && c <= '9')
     8         num = num * 10 + c - '0', c = getchar();
     9     return num;
    10 }
    11 
    12 const int maxn = 5e4 + 5;
    13 
    14 int L, n, m, stone[maxn];
    15 
    16 inline int check(int x) {
    17     int cnt = 0, last = 0;
    18     for (int i = 1; i <= n; ++i) {
    19         if (stone[i] - stone[last] < x) ++cnt;
    20         else last = i;
    21     }
    22     if (cnt <= m) return 1;
    23     else return 0;
    24 }
    25 
    26 int main() {
    27     L = get_num(), n = get_num(), m = get_num();
    28     for (int i = 1; i <= n; ++i) stone[i] = get_num();
    29     int l = 1, r = L + 1;
    30     while (r - l > 1) {
    31         int mid = l + (r - l) / 2;
    32         if (check(mid)) l = mid;
    33         else r = mid;
    34     }
    35     printf("%d", l);
    36     return 0;
    37 }
    AC代码
  • 相关阅读:
    i5ting_doc的安装和使用
    vscode—修改默认的shell
    cookie的相关知识
    这是一段有毒的js代码,求大神解释!!!
    BFC的触发条件
    替换元素与非替换元素
    css中em的使用方法
    误操作导致ps界面中的工具栏消失
    导航栏里面的li标签和a标签的配合使用
    记录一下 elmentui 循环复选框不能选中问题
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9538431.html
Copyright © 2011-2022 走看看