二分答案模板

【模板+讲解】二分答案

!阅读须知||阅读本博文前笔者认为读者已经学会(或了解)了:

1.基础语言与算法

2.标准二分法(二分思想)

3.二分查找

定义

二分答案与二分查找类似,即对有着单调性的答案进行二分,大多数情况下用于求解满足某种条件下的最大(小)值。

答案单调性

答案的单调性大多数情况下可以转化为一个函数,其单调性证明多种多样,如下:

  1. 移动石头的个数越多,答案越大(NOIP2015跳石头)。
  2. 前i天的条件一定比前 i + 1 天条件更容易(NOIP2012借教室)。
  3. 满足更少分配要求比满足更多的要求更容易(NOIP2010关押罪犯)。
  4. 满足更大最大值比满足更小最大值的要求更容易(NOIP2015运输计划)。
  5. 时间越长,越容易满足条件(NOIP2012疫情控制)。

可以解决的问题

  1. 求最大的最小值(NOIP2015跳石头)。
  2. 求最小的最大值(NOIP2010关押罪犯)。
  3. 求满足条件下的最小(大)值。
  4. 求最靠近一个值的值。
  5. 求最小的能满足条件的代价。

代码

为了保证解在二分搜索的区间里,故不同的问题有着不同(但相似)的写法,读者可以画一个区间模拟一下~

求最小值

int binary()
{
    int l = 0, r = ll, mid;
    while(l < r)
      {
        mid = (l + r) >> 1;
        if(check(mid)) r = mid;  //大多数题只要改改check()即可
        else l = mid + 1;
      }
    return l;
}

求最大值

int binary()
{
    int l = 0, r = ll, mid;
    while(l < r)
      {
        mid = (l + r + 1) >> 1;
        if(check(mid)) r = mid - 1;
        else l = mid;
      }
    return l;
}

面对整数时的万能二分(近似万能)

int binary(int n)
{
    int l = 1, r = maxn, ans = 0;
    while(l <= r)
      {
        int mid = (l + r) >> 1;
        if(c[mid] > a[n]) ans = mid, l = mid + 1;  //判断条件与ans记录位置因题而异
        else r = mid - 1;
      }
    return ans;
}

原文地址:https://www.cnblogs.com/fzl194/p/8971343.html

时间: 2024-10-08 06:17:34

二分答案模板的相关文章

c++二分答案 之 跳石头

题目: 题目描述 Description 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有N块岩石(不含起点和终点的岩石).在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点. 为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长.由于预算限制,组委会至多从起点和终点之间移走M块岩石(不能移走起点和终点的岩石). 输入描述 Inp

二分答案的模板

二分答案是求解最大中的最小值或最小中的最大值的常用解法,模板如下: while(r-l>1){ mid=(l+r)>>1; if(judge(mid)){ l=mid; //左边界右移 }else{ r=mid; //右边界左移 } } if(judge(r)) cout<<r; else cout<<l; 原文地址:https://www.cnblogs.com/MS903/p/11247826.html

二分算法模板

二分算法求最值,掌握了算法的本质和模板,主要就是答案验证过程,验证过程经常使用贪心算法. 关键是根据题目要求设立命题check(x). 验证答案mid: Check(mid):是否成立? 求满足条件Check(mid)的最小值: –if  check(mid) then r:=mid else l:=mid+1; 求满足条件Check(mid)的最大值: –if  check(mid) then l:=mid else r:=mid-1; 模板一:求满足条件check(mid)的最小值. 1 /

codeforces 359D 二分答案+RMQ

上学期刷过裸的RMQ模板题,不过那时候一直不理解>_< 其实RMQ很简单: 设f[i][j]表示从i开始的,长度为2^j的一段元素中的最小值or最大值 那么f[i][j]=min/max{d[i][j-1], d[i+2^j-1][j-1]} RMQ的ST算法: 1 void ST() //初始化 2 { 3 memset(RMQ,1,sizeof(RMQ)); 4 5 for(int i=1;i<=n;i++) 6 RMQ[i][0]=a[i]; 7 for(int j=1;(1<

POJ--2391--Ombrophobic Bovines【拆点+Floyd+Dinic优化+二分答案】网络最大流

链接:http://poj.org/problem?id=2391 题意:有f个草场,每个草场当前有一定数目的牛在吃草,下雨时它可以让一定数量的牛在这里避雨,f个草场间有m条路连接,每头牛通过一条路从一点到另一点有一定的时间花费,现在要下雨了,农场主发出警报牛就会立即去避雨.现在告诉每个草场的情况,以及m条边的信息.农场主至少需要提前多久发出警报才能保证所有牛都能避雨?如果不是所有牛都能成功避雨输出-1. 思路:这道题需要拆点,是看到魏神的博客才知道的,我们把原图拆成一个二分图,避免突破最大距离

POJ--2289--Jamie&#39;s Contact Groups【二分图多重匹配+二分答案】

链接:http://poj.org/problem?id=2289 题意:有n个人,m个分组,每个人可以分配到一些组别,问如何分能使得人数最多的组别人数最少. 思路:这道题二分+网络流也可以做,我这里是二分图多重匹配的做法.因为一个组别是一对多的关系,所以是多重匹配,我们二分多重匹配的限制,得到最小的限制可使二分图匹配,这个限制就是答案. 网上找的模板 #include<cstring> #include<string> #include<fstream> #inclu

【笔记】二分答案

二分答案 O(nlogm) 对一段有序的序列 每次二分,从而快速的查找.解决的问题常是"使最大值最小"或"使最小值最大". 注意:①注意二分的序列是有序的,对于无序的序列进行二分需要先排序. ②二分的区间尽可能大(给定区间左右端点+-1) ③根据题目要求,设定好check函数. ④防止死循环.↓ 模板: 1 //第一种 2 while(r-1>l) 3 { 4 int mid=(l+r)>>1; 5 if(check(mid)) l=mid; 6

[POJ2976][POJ2728]01分数规划问题的二分答案解法

这里就不放原题目了. POJ2976就是01分数规划的模板题,题目形式就是有n个物品,每个物品有对应的价值ai和代价bi,我们要取K个物品,使取的物品的  最小. 二分答案的解法特别妙,我们设 r= ,那么就有   由此不难发现,只要满足这条式子,我们能取的r越大越好. 不难发现此时已经满足二分答案的性质了. 二分r的大小,如果最后式子左边大于0,那么说明r取小了,如果左边小于0,说明r取大了. 那么我的代码如下: #include<iostream> #include<cstdio&g

分治 二分答案 三分未完结

分治,字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.分治法是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)等等. 分治三步法: 1 划分问题:把问题划分成元素个数尽量相等的两半: 2 递归求解:把两半元素分别求解: 3 合并问题:把两个已经求解的元素合并成一个: 二分的基本用途是在单调序列或单调函数中做查找操作,注意:二