zoukankan      html  css  js  c++  java
  • Divide and Conquer:River Hopscotch(POJ 3258)

                    

                      去掉石头

      题目大意:一群牛在河上的石头上跳来跳去,现在问你如何通过去掉M个石头,使得牛跳过石头的最短距离变得最大?

      这一题比较经典,分治法的经典,二分法可以很方便处理这个问题,我们只要明白比较函数这个东西就可以了。

      模板:

        while (……)
        {
            mid = (lb + rb) / 2;
            if (Judge_C(……))
            else rb = mid;
        }

      while判断条件可以根据是整形还是浮点型灵活变换,Judge_C就是比较函数,几乎所有的分治算法都可以这样归纳,我们只要找到合适的比较函数就可以了

      对于这题来说,他的比较函数可以这样看,我们先把石头去掉M个,然后在这些位置摆上,求最大的那个最短距离。

      这样一来,我们只用规定好上限就可以了(上限是length+1)

      

     1 #include <functional>
     2 #include <iostream>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 void Search(const int, const int);
     8 bool Judge_C(const int, const int, const int);
     9 
    10 static int rock[50005];
    11 static int Min_Step;
    12 
    13 int main(void)
    14 {
    15     int Length, M, Block_Sum;
    16     while (~scanf("%d%d%d", &Length, &Block_Sum, &M))
    17     {
    18         for (int i = 1; i <= Block_Sum; i++)
    19             scanf("%d", &rock[i]);//rock储存的位置
    20 
    21         rock[0] = 0;
    22         rock[Block_Sum + 1] = Length;//把开始的位置和结束的位置都存在数组里面
    23         
    24         sort(rock, rock + Block_Sum + 2);
    25         Search(M, Block_Sum);
    26     }
    27     return 0;
    28 }
    29 
    30 bool Judge_C(const int M, const int Block_Sum, const int min_distance)
    31 {
    32     int last = 0, pos = 0;
    33 
    34     for (int i = 0; i < Block_Sum - M; i++)
    35     {
    36         pos = last + 1;
    37         while (pos <= Block_Sum && rock[pos] - rock[last] < min_distance)
    38             pos++;
    39         if (pos == Block_Sum + 1)
    40             return false;
    41         last = pos;
    42     }
    43     return true;
    44 }
    45 
    46 void Search(const int M, const int Block_Sum)
    47 {
    48     int lb = 0, rb = rock[Block_Sum + 1] + 1, mid;
    49 
    50     while (rb - lb > 1)
    51     {
    52         mid = (lb + rb) / 2;
    53         if (Judge_C(M, Block_Sum, mid))
    54             //判断C(x):把去掉M个石头看成去掉在这些位置放Block_Sum-M个石头
    55             //注意上界是L+1,然后用二分逼近
    56             lb = mid;
    57         else rb = mid;
    58     }
    59     printf("%d
    ", lb);
    60 }

  • 相关阅读:
    工作中用到知识点
    工作中遇到问题的解决办法
    透明度兼容性(ie8以上)
    js阻止浏览器默认行为
    js停止冒泡和阻止浏览器默认行为
    js添加事件通用方法
    jquery常用插件
    延迟加载、异步加载js
    JavaScript兼容性问题
    创建对象的一种方式&一种继承机制(代码实例)
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5062347.html
Copyright © 2011-2022 走看看