二分算法总结

一、三个板子:

int l,r;
while(l>1;
    if(check(mid)) r=mid;
    else l=mid+1;
}
int l,r;
while(l>1;
    if(check(mid)) l=mid;
    else r=mid-1;
}
double l,r;
while(r-l>1e-6){
    int mid=(l+r)/2;
    if(check(mid)) l=mid;
    else r=mid;
}

二、对于check()函数:

1.理解:

check()函数 表示的是一个状态,首先要确定你所要查找的答案的性质(你要的状态)是什么,这点对于二分很重要,因为二分的必要条件就是一个区间内可以分为两种状态,一种状态在左侧,另一种状态在右侧(即:左右两侧中,有一侧满足你要的状态,另一侧则不满足) ,那么,区分这两侧的分界点就是我们要二分查找的点 (二分算法就是用来干这个的)

2.详细步骤:

(1)先假设我们要找的分界点,并确定我们要的性质(状态)

(2)判断我们二分的mid在check()之后如果在我们要的状态的那一侧,那么就应该让区间那一侧的端点往另外一侧移。即:mid在右侧的状态区间的话就往左移,在左侧的状态区间的话就往右移

        对应的几道题目会更好理解:

        acwing 113.特殊排序
        AcWing 789. 数的范围

三、二分答案:

对于二分答案,我个人的理解是:首先自己要开一个足够大的区间(答案的数值就在这个区间里),然后判断我们二分的答案经过check()之后最终是否满足题干中给出的另外一个条件

那么这个条件我们应该如何判断取哪个呢?通常,题干中会有“是否存在” 、“最多(大)” 、“最少(小)” 这样的字眼,那么这些条件就可能是我们要判断的条件。

        下面给出两道题:(这两道题除了涉及二分答案,还有很多其他的做题细节,值得一看)

       102. 最佳牛围栏(已做笔记)        P3743 kotori的设备 (已做笔记)

四、二分边界问题:

对于二分来说,有可能二分到开头或末尾,但是我们做题时有可能碰到与二分点的前一个或后一个有关的问题,如果二分到最后一个点,那就无法判断最后一个点是刚好满足条件的还是不能满足的,所以我们可以在序列(数组)的开头和末尾分别再补上一个数据

放一道题目:P1678 烦恼的高考志愿

你可能感兴趣的:(算法,c++)