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. ...
随机推荐
- vue中this.$router.push() 传参
1 params 传参 注意⚠️:patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据 this.$router.push({name: 'dispatch', para ...
- java——删除HashMap中所有的键值对
第一种:❌(报错) import java.util.HashMap; import java.util.Set; public class T{ public static void main(St ...
- Git简单上传和下载
本文参考 git-简易指南 编写 上传本地代码到gitHub仓库 第一步:建立git仓库 cd到你的本地项目根目录下,执行git命令 git init 第二步:将项目的所有文件添加到仓库中 git a ...
- 性能测试工具LoadRunner15-LR之负载生成器(Load Generators)
简介 对场景进行设计后,需要对负载生成器进行管理和配置.Load Generators是运行脚本的负载引擎(相当于加压机)主要功能是生成虚拟用户进行负载,在默认情况下使用本地的负载生成器来运行脚本. ...
- Murano Weekly Meeting 2015.10.06
Meeting time: 2015.October.6th 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summar ...
- https的设计原理
参考文章: https://www.cnblogs.com/zhangshitong/p/6478721.html http://blog.jobbole.com/113883/ 这两篇文章写的非常好 ...
- java内存区域与内存溢出
JVM的内存区域划分: jvm的内存区域分为5部分:程序计数器,虚拟机栈,本地方法栈,堆跟方法区. 程序计数器,虚拟机栈,本地方法栈三部分是线程私有的,堆跟方法区是公共的. 1.程序计数器 是一块较小 ...
- 用spring的 InitializingBean 的 afterPropertiesSet 来初始化
void afterPropertiesSet() throws Exception; 这个方法将在所有的属性被初始化后调用. 但是会在init前调用. 但是主要的是如果是延迟加载的话,则马上执行. ...
- Spring boot-(3) Spring Boot特性1
本节将深入Spring Boot的细节,可以学到你想使用的或定制的Spring Boot的主要特性. 1. SpringApplication SpringApplication类为引导一个Sprin ...
- HDU 5418——Victor and World——————【状态压缩+floyd】
Victor and World Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Other ...