二分模板一共有两个,分别适用于不同情况。
算法思路:假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l = r时,我们就找到了目标值。

版本1

在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)low_bound

当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

C++ 代码模板:

int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;//同l+( r-l )/2;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
版本2

在单调递增序列a中查找<=x的数中最大的一个(即x或x的前驱)upper_bound

当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

C++ 代码模板:

int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;//同 l+1+( r-l )/2;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}

简单总结一下就是在[0,0,0,...,0] (共k个数) 里面搜索0。

使用第一个会返回位置0

使用第二个会返回k - 1

也可以看做寻找 第一个<= target的元素 和 最后一个<= target的元素

 二分答案转化为判定

一个宏观的最优化问题也可以抽象为函数,其“定义域”是该问题下的可行方案,对这些可行方案进行评估得到的数值构成函数的“值域”,最优解就是评估值最优的最优解就是评估值最优的方案(不妨设评分越高越优)。假设最优解的评分是S,显然对于任何x>S,都不存在一个合法的方案达到x分,否则就与S的最优性矛盾:而对于任何x≤S,一定存在一个合法的方案达到或超过x分,因为最优解就满足这个条件。这样问题的值域就具有一种特殊的单调性,在S的一侧合法、在S的另一侧不合法,就像一个在(-∞,S]上值为1,在(S,+∞]上值为0的分段函数,可通过二分找到这个分界点S。借助二分,我们把求最优解的问题,转化为给定一个值mid,判定是否存在一个可行方案评分达到mid的问题。接下来我们通过一个经典的例子理解上述概念。

有N本书排成一行,已知第i本的厚度是Ai,把它们分成连续的M组,使T最小化,其中T表示厚度之和最大的一组的厚度。题目描述中出现了类似于“最大值最小”的含义,这是答案具有单调性,可用二分转化为判定的最常见、最典型的特征之一。如果我们以“把书划分为M组的方案”作为定义域,“厚度之和最大的一组的厚度”作为评分(即值域),需要最小化这个厚度值,也就是评分越小越优。相应地,假设最终答案为S,因为S的最优性,如果要求每组的厚度都<S,那么这M组一定不能容纳这些书,可能需要更多的组才能把书分完,也就意味着对于本题的限制条件不存在可行的分书方案。如果每组的厚度可以>S那么一定存在一种分书方案使得组数不会超过M。最优解就处于分书可行性的分界点。

0x40二分法的更多相关文章

  1. C语言两种查找方式(分块查找,二分法)

    二分法(必须要保证数据是有序排列的):   分块查找(数据有如下特点:块间有序,块内无序):    

  2. poj3122-Pie(二分法+贪心思想)

    一,题意: 有f+1个人(包括自己),n块披萨pie,给你每块pie的半径,要你公平的把尽可能多的pie分给每一个人 而且每个人得到的pie来自一个pie,不能拼凑,多余的边角丢掉.二,思路: 1,输 ...

  3. 二分法&三分法

    ural History Exam    二分 #include <iostream> #include <cstdlib> using namespace std; //二分 ...

  4. [No000087]Linq排序,SortedList排序,二分法排序性能比较

    using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; ...

  5. [PHP]基本排序(冒泡排序、快速排序、选择排序、插入排序、二分法排序)

    冒泡排序: function bubbleSort($array){ $len=count($array); //该层循环控制 需要冒泡的轮数 for($i=1;$i<$len;$i++){ / ...

  6. iOS常见算法(二分法 冒泡 选择 快排)

    二分法: 平均时间复杂度:O(log2n) int halfFuntion(int a[], int length, int number)  { int start = 0; int end = l ...

  7. java简单的二分法排序

    二分法排序的思路:数据元素要按顺序排列,对于给定值 x,从序列的中间位置开始比较,如果当前位置值等于 x,则查找成功:若 x 小于当前位置值,则在数列的前半段中查找:若 x 大于当前位置值则在数列的后 ...

  8. 使用二分法查找mobile文件中区号归属地

    #!/usr/bin/env python #coding:utf-8 ''' Created on 2015年12月8日 @author: DL @Description: 使用二分法查找mobil ...

  9. Atitit 迭代法  “二分法”和“牛顿迭代法 attilax总结

    Atitit 迭代法  "二分法"和"牛顿迭代法 attilax总结 1.1. ."二分法"和"牛顿迭代法"属于近似迭代法1 1. ...

随机推荐

  1. hive export import

    create database target_db; drop table target_db.kylin_account; dfs -rm -r /tmp/kylin_account; export ...

  2. jconsole如何查看

    https://www.jdon.com/idea/jvm-gc.html 场景: https://www.cnblogs.com/yszzu/p/9648579.html    查看大对象到底占用多 ...

  3. 锁、CAS操作和无锁队列的实现

    https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...

  4. linux开机启动服务学习chkconfig命令

    选项: --add:增加所指定的系统服务,让chkconfig指令得以管理它,并同时在系统启动的叙述文件内增加相关数据: --del:删除所指定的系统服务,不再由chkconfig指令管理,并同时在系 ...

  5. 2.1 Rust概念

    标识符 The first character is a letter.The remaining characters are alphanumeric or _.或The first charac ...

  6. pdf.js使用爬过的坑

    最近项目里需要做一个在浏览器直接预览pdf的功能,有些浏览器可以直接预览pdf文件,但是有些不能(不要躲,说的就是你IE)查资料普遍推荐pdf.js,兼容能到ie9,很不错了. 1. 从pdf.js官 ...

  7. [转]IE和FireFox中JS兼容之event .

    转载于:http://blog.csdn.net/jiachunfeng/article/details/6448186 http://justcoding.iteye.com/blog/587876 ...

  8. LeetCode 981.基于时间的键值存储(C++)

    创建一个基于时间的键值存储类 TimeMap,它支持下面两个操作: 1. set(string key, string value, int timestamp) 存储键 key.值 value,以及 ...

  9. jQuery源代码学习笔记_01

    如何获取jQuery源代码 1.可以从GitHub上下载到没有合并和压缩的源代码 2.如果要查看兼容IE6-8的版本,请选择1.x-master分支 3.可以使用git clone也可以使用downl ...

  10. 【ubuntu】安装之后要安装的一些东西

    问题1: ubuntu默认没有安装vim,出现: root@evelyn-virtual-machine:~# vim /etc/ssh/sshd_config The program 'vim' c ...