Nefu寒假集训: 二分法总结

一.使用二分需要满足两个条件:有界性和单调性

有界性:有界二分答案应在一个闭区间上进行;
单调性:问题的解分布在一个区间上,这里有很多不合法的解,也有很多合法的解.考虑所有合法(可行)解,目标是从这些可行解中找到一个最优的作为答案. 注意到最优解一定可行,但可行解不一定最优.假设整个序列具有单调性,一般地,若一个数 x x x为合法解,则对 ∀ x ′ < x {\forall}x'<x x<x,都是合法解.若有一个数 y y y是非法解,则对 ∀ y ′ > y {\forall}y'>y y>y,都是非法解.正是因为有单调性的存在,才使得每次舍弃解区间的一半 [ l , m i d ] [l,mid] [l,mid] [ m i d , r ] [mid,r] [mid,r]这种优化是正确的,因为保证舍弃的区间一定是非法解区间.

二.二分法模板(二分答案与二分查找)

二分法总是可以分成"求满足某条件的最大值"与"满足条件的最小值"两种情况,
其中"某条件"常常被封装成check()函数 判断当前解是否可行.
(1)整数域的二分

//寻找满足条件的最小值
int l=0,r=n,mid;
while (l<r)
{
	mid=(l+r)/2;
	
	if (check(mid))
		r=mid;
	else
		l=mid+1;
}
//l即为所求
//寻找满足条件的最大值
int l=0,r=n,mid;
while (l<r)
{
	mid=(l+r+1)/2;
	
	if (check(mid))
		l=mid;
	else
		r=mid-1;
}
//l即为所求

(2)实数域的二分
与整数域上的二分相比有变动,求mid时不在加1;else后也不再加1或减1;

三.二分法的应用:二分查找.查找有序序列中的元素,返回下标

1.如:求序列中第一个大于x的元素的下标,等价于寻找满足x<a[mid]的最小mid
求序列最后一个小于等于x的元素的下标,等价于寻找满足x>=a[mid]的最大mid

2.事实上,C++中封装了两个函数,可以方便地实现二分查找
upper_bound()返回第一个大于某元素的下标;等价于寻找满足a[mid]>x的最小值
lower_bound()返回第一个大于等于元素的下标;等价于寻找满足a[mid]>=x的最小值
如:

int tmp = upper_bound(a, a + 5, 7) - a;
/*data:
9
20 20 40 40 40 60 60 80 80
9
15 20 35 40 45 60 75 80 85*/

四.二分法的应用:二分答案.

如:最大(小)值最小(大)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值