0x40二分法
二分模板一共有两个,分别适用于不同情况。
算法思路:假设目标值在闭区间[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二分法的更多相关文章
- C语言两种查找方式(分块查找,二分法)
二分法(必须要保证数据是有序排列的): 分块查找(数据有如下特点:块间有序,块内无序):
- poj3122-Pie(二分法+贪心思想)
一,题意: 有f+1个人(包括自己),n块披萨pie,给你每块pie的半径,要你公平的把尽可能多的pie分给每一个人 而且每个人得到的pie来自一个pie,不能拼凑,多余的边角丢掉.二,思路: 1,输 ...
- 二分法&三分法
ural History Exam 二分 #include <iostream> #include <cstdlib> using namespace std; //二分 ...
- [No000087]Linq排序,SortedList排序,二分法排序性能比较
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; ...
- [PHP]基本排序(冒泡排序、快速排序、选择排序、插入排序、二分法排序)
冒泡排序: function bubbleSort($array){ $len=count($array); //该层循环控制 需要冒泡的轮数 for($i=1;$i<$len;$i++){ / ...
- iOS常见算法(二分法 冒泡 选择 快排)
二分法: 平均时间复杂度:O(log2n) int halfFuntion(int a[], int length, int number) { int start = 0; int end = l ...
- java简单的二分法排序
二分法排序的思路:数据元素要按顺序排列,对于给定值 x,从序列的中间位置开始比较,如果当前位置值等于 x,则查找成功:若 x 小于当前位置值,则在数列的前半段中查找:若 x 大于当前位置值则在数列的后 ...
- 使用二分法查找mobile文件中区号归属地
#!/usr/bin/env python #coding:utf-8 ''' Created on 2015年12月8日 @author: DL @Description: 使用二分法查找mobil ...
- Atitit 迭代法 “二分法”和“牛顿迭代法 attilax总结
Atitit 迭代法 "二分法"和"牛顿迭代法 attilax总结 1.1. ."二分法"和"牛顿迭代法"属于近似迭代法1 1. ...
随机推荐
- Win10通过SSH与树莓派Raspbain系统互传文件
1.在Linux系统上安装ssh-server(由于Raspbain系统自带ssh-server,这个步骤可以省略) 查看ssh是否运行的命令: ps -ef | grep ssh 如果没有安装,则安 ...
- 效率工具(fswatch,rsync)
mac 安装 brew: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/in ...
- 正则表达式获取多个img src的值
/** * 得到网页中图片的地址 */public static Set<String> getImgStr(String htmlStr) { Set<String> pic ...
- Unity [SerializeField]
在Unity3d中Unity3D 中提供了非常方便的功能可以帮助用户将 成员变量 在Inspector中显示,并且定义Serialize关系. 也就是说凡是显示在Inspector 中的属性都同时具有 ...
- Misc1
什么是编译进内核与制作成模块 编译进内核意味着内核对这一类的功能不会在依赖其他的东西, 说白了就是所谓静态编译, 内核在启动的时候就会拥有这一部分的功能, 但是这样内核的体积就会变大 编译成模块, 其 ...
- HDU 4357——String change——————【规律题】
String change Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- BNU 26349——Cards——————【区间dp】
题目大意:给你n张牌,排成一排放在桌子上,可以从左端拿也可以从右端拿.现在有A,B两人轮流取牌,A先取,两人足够聪明,即都想取最大的牌总和,问A能取到的最大值. 解题思路:定义dp[i][j][k]. ...
- dreamweaver,access2010,数学
dreamweaver 1,点插入-表格-设置表格. 2,再次修改表格,打开属性修改指标. (修改图片时,也可以选中图片打开对应的属性修改) 设置字体: 1,打开属性-页面属性,弹出操作窗口,设置想改 ...
- C++中的虚函数表
(感谢http://blog.csdn.net/haoel/article/details/1948051/) C++中的虚函数的作用主要是实现了多态的机制. 多态,简而言之就是用父类型别的指针指向其 ...
- 常规项目用到的jar包之maven的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...