二分答案

二分答案

二分答案,就是用二分的方法,在可能的答案区间里找出问题的答案,大多数情况下用于求解满足某种条件下的最大(小)值,前提是答案具有单调性,同时也可以理解为是一种倒推方法(先找答案在判断答案是否可行、有没有更优解)。

二分答案的主要思想

• 在答案的可能范围(区间)内二分枚举
• 并检查所穷举的答案是否符合题意
• 将最优性问题(直接求解相对较难)
• 转化为可行性问题(答案是否符合题意相对容易)

二分答案有两种情况:
下图中L,R为当前答案区间,M为中心点,根据二分思想判断M是否符合条件,再移动L或R,变成L’,R’,图中的T和F表示是否符合条件。

1.最小值最大化

  int l = min_ans, r = max_ans;
    while (l < r) {
    	int mid = (l + r + 1) / 2;   //+1避免 r == l + 1 时mid一直等于l,从而死循环
    	if (OK(mid))	//符合条件返回True
    		l = mid;
    	else
    		r = mid - 1;
    }

希望答案尽可能大,所以我们需要确保左区间L点符合题目条件(最小),至于R是否符合条件是不确定的,首先判断M点符合与否,符合则将L移到M点,维持了L的True属性,也增大了所要的最小值所在区间,如果不符合,没办法在保持L的True属性情况下移动L,那就移动R。

2.最大值最小化

  int l = min_ans, r = max_ans;
    while (l < r) {
    	int mid = (l + r) / 2;
    	if (ok(mid))	//符合条件返回True
    		r = mid;
    	else
    		l = mid + 1;
    }

按同样道理分析,维持R的True属性即可。这里的mid就不需要加1了,因为 mid 跟 l 重合时,l = mid + 1;会自增,而当 mid 和 r 重合时 l 也跟 r 重合,结束循环了。

注意点

  1. 每次循环都要确保L和R有一个被更新,否则就会出现死循环
  2. 答案是浮点数的情况:区间更新不能加1,这样变动太大,直接进行以下操作:
  l = mid;
  r = mid;

例题:https://www.luogu.com.cn/problem/UVA10566

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值