二分法讲解

二分法讲解

二分的本质 : 按一定性质可以将序列一分为二

整数集合上的二分

最终答案处于闭区间[l, r]以内,处理的内容是[l, r)的集合,循环以l == r结束,每次二分的中间值mid会归属左半段与右半段二者之一。

查找右半段的集合,单调递增序列a中查找>= x最小的一个,即x或x的后继

    while l < r :
	    mid = (l + r) >> 1 # 右半段集合 + 0
	    r = mid if a[mid] >= x else l = mid + 1
    return a[l]

查找左半段集合,单调递增序列a中查找<= x最大的一个,即x或x的前驱

    while l < r :
    	mid = (l + r + 1) >> 1 # 左半段集合 + 1
    	l = mid if a[mid] <= x else r = mid - 1
    return a[l]

通过将集合扩大的方式,来处理无解情况

查找右半边的话将集合[1, n]扩大为[1, n + 1],把越界的下标包含进来。
查找左半边的话将集合[1, n]扩大为[0, n],把越界的下标包含进来。

如果最后二分终止与扩大后的这个越界下标上,则说明a中不存在所求的数。

流程

  1. 具体分析题目,确定左右半段哪个是可行区间,以及mid归属哪一段
  2. 选择r,l,mid形式。
  3. 终止条件为l == r,该值就是答案所在。

实数域上的二分

确定好精度eps,一般需要保留k位小数,esp = 10 ^-(k + 2);

    while l + 1e-5 < r :
        mid = (l + r) / 2;
        if calc(mid) > target: r = mid
        else : l = mid
    } 

精度不好确定,则采取循环固定次数的二分法

	for i in range(100) :
		mid = (l + r) >> 1
		if calc(mid) > target : r = mid
		else : l = mid

三分求单峰函数极值

以单峰函数f为例,定义域[l, r]任取两个点lmid与rmid
f(lmid) < f(rmid), lmid肯定在极大值左侧,所以l = lmid
f(lmid) > f(rmid), r = rmid

lmid与rmid取的距离二等分点两侧极近的地方越好
若存在f(lmid) == f(rmid),则不能用三分法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值