二分搜索总结

所谓二分法,在C++ STL中就一句话, l o w e r _ b o u n d lower\_bound lower_bound,但是写了几道题,发现真正使用的时候其实充满了技巧。

  1. 假定一个解并判断是否可行的问题
  2. 最大化最小值的问题

这两个问题其实联系很大,他们有着共同的思路,即
(1)将所要求的结果当做二分查找的对象,确定 [ l , r ] [l,r] [l,r]区间,
(2)确定某个 m i d = ( l + r ) > > 1 mid=(l+r)>>1 mid=(l+r)>>1是否是一个可行解,根据是否可行解更新 l , r l,r l,r的值,直到循环结束。

往往确定其是可行解的过程稍微复杂一点,但是理清思路可能并不是很难,直到我看到另一道题

一道常规又非常规的题在这里插入图片描述

看到题的一瞬间greedy涌上我的心头,题解一看第一句话
在这里插入图片描述
我们只能保证单个物品的单位价值最大,但greedy不能保证多个物品加起来的单位价值最大。不妨再次考虑二分查找,将目标值:单位价值作为搜索目标,那么剩下的问题就是可行解的判断了,我们所要判断的是对于一个 m i d mid mid值,是否可以选择一个集合 S \mathcal{S} S,使得该集合的单位价值大于 m i d mid mid。如果可以,那么 l = m i d l=mid l=mid,否则 r = m i d r=mid r=mid。这样就将其完整的转化成了一个二分搜索问题。

难点:可行解的判断

∑ i ∈ S v i / ∑ i ∈ S w i ≥ x i \sum_{i\in \mathcal{S}}v_i/\sum_{i\in \mathcal{S}}w_i\geq x_i iSvi/iSwixi
∑ i ∈ S ( v i − x i w i ) ≥ 0 \sum_{i\in \mathcal{S}}(v_i-x_iw_i)\geq 0 iS(vixiwi)0
也就是说只要保证集合 S \mathcal{S} S内所有的元素的 ( v i − x i w i ) (v_i-x_iw_i) (vixiwi)之和大于等于0即可,此时贪心是没有问题的,根据 ( v i − x i w i ) (v_i-x_iw_i) (vixiwi)将集合排序,只要前 k k k个物品满足此性质即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值