二分法的思路

整数二分法

不要纠结是左端点还是右端点的弄法,跟着题目走,比如题目说要你在上升序列中取小于t的最大的数,那就顺着写呗。a【mid】是不是要小于t,此时mid是不是在t左边且符合条件,那mid是不是就是l=mid,如果不满足是不是mid就在t的右边而且这个答案肯定不是mid,所以r=mid-1

1、确定一个区间,使得目标值一定在区间中

2、找一个性质,这个性质满足:

(1)这个性质具有二段性

(2)它可以让我们想要的答案成为二段性的分界点

 第一类:ans是红色区间右端点(对应图中ans在下面)

将【L,R】分成[L,M-1][M,R]

if M是红色的(在红色区域中),则答案必然在[M,R]之间的

else 说明ans在【L,M-1】

while(l<r){
    m=(l+r+1)/2;
    if m 红 : l=m;
    else    : r=m-1;
}
// 在单调递增序列a中查找<=x的数中最大的一个(即x或x的前驱)
while (low < high)
{
    int mid = (low + high + 1) / 2;

    if (a[mid] <= x)//mid落在红色区域
        low = mid;

    else
        high = mid - 1;
}

注意!!!

查找右端点时,我们相当于是求满足条件的最大数为多少,(<t的最大数)所以满足条件的一定是左端,并且左端取等,不满足条件的一定比右端右,所以减一

第二类:ans是蓝色区间左端点(对应图中ans在上面)

将【L,R】分成[L,M-1][M,R]

if M是蓝色的(在蓝色区域中),则答案必然在【L,M】之间的

else 说明ans在【M+1,R】

while(l<r){
    m=(l+r)/2;
    if m在蓝色 : R=m;
    else    : L=m+1;
}
// 在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)
while (low < high)
{
    int mid = (low + high) / 2;
    if (a[mid] >= x)//mid落在蓝色区域
        high = mid;

    else
        low = mid + 1;
}

不用考虑这么多,只要考虑是L=M还是R=M就行了

算法步骤:

1、找区间【L,R】,答案在其中

2、找一个判断条件,使得该判断条件具有二段性,并且答案一定是该二段性的分界点

3、分析终点M在该判断条件下是否成立。如果成立,考虑答案在哪个区间,如果不成立,考虑答案在哪个区间;

4、如果更新方式写的是R=MID,则不用做任何操作,如果更新方式是L=MID,则需要在计算MID的时候加上1

实数二分法

因为是落实到一个数所以不需要分两种情况

while (high - low > 1e-6)(1e-n,n根据题目对小数位数的精度要求再加2)
{
    double mid = (low + high) / 2;
    if (a[mid] >= x)//mid落在蓝色区域
        high = mid;

    else
        low = mid;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值