• 二分与三分


    1.介绍一下二分

    • 什么是二分?

    二分法,顾名思义,就是一次分成两份,实际也就是这样(其实并不是

    咳咳,二分法,就是在一个单调有序的序列(或者集合,函数,只要是单调有序的就行)中查找一个解,每次把当前的范围从中间劈开分为左右两部分,然后判断解在哪个部分中并且不断地调整上下界,直到找到答案。

    二分是一种常用的算法,常常是我们解决问题的突破口(在你没有思路的时候暴力二分求解)。

    二分的基本用途是在单调序列或者单调函数中进行查找操作。因此如果问题的答案具有单调性,就可以考虑二分判定

    是的,二分和判定

    如果你只二分而不判定的话,就无法继续二分,也无法退出二分,就相当于你卡在了一个非常尴尬的位置上

    所以二分的时间复杂度为O(二分次数*单次判定的复杂度)

    如果是在正整数上二分的话,二分次数就是log n,判定结束二分时只需要看看目前左右端点是否一样就行了

    而如果是在实数上二分的话,就需要判定精度,abs(l-r)是否小于给定的精度

    • 二分要注意的事项

    1.单调性,单调性,单调性(重要的事情说三遍)

      只有具有单调性的集合或者函数才可以用二分,否则就算你分出来了区间也不能进行下一步的操作。如果当前给定的数据不具有单调性,你不妨给他排一下序

    2.虽然你使用了二分,而且单纯的二分复杂度也不是很高,但你还是要好好写一写检查的函数,否则还是会TLE

    2.二分的常见模型

    1.二分答案

      看到最小值最大或者是最大值最小的问题,基本上就是二分没跑了,需要在确定答案后,配合其他算法检查这个答案是否合理

    2.二分查找

      用具有单调性的布尔表达式求解分界

    3.代替三分

      有的时候对于一些单峰函数,我们可以用二分导函数的方法求解函数极值(什么是导函数?详情参见百度百科或高中选修2-3或高等数学(一)

    3.二分板子

    1.整数定义域上的二分

    代码:

    bool check(int l)
    {
        //......
    }
    
    int erfen(int 1,int n)
    {
        int l=1,r=n;
        int ans;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)) r=mid;
            else l=mid;
        }
        return l;
     } 

    2.实数定义域上的二分

    代码:

    double eps=0.001;//这个随着题目要求而改变 
    
    bool check(double l)
    {
        //......
    }
    
    double erfen(double 1,double n)
    {
        double l=1,r=n;
        double ans;
        while(fabs(l-r)>eps)
        {
            double mid=(l+r)/2.0;
            if(check(mid)) r=mid;
            else l=mid;
        }
        return l;
     } 

    (在你没有思路的时候暴力二分求解

  • 相关阅读:
    git
    oracle object_id和data_object_id的区别
    statspack系列8
    statspack系列7
    statspack系列6
    statspack系列5
    statspack系列4
    statspack系列3
    statspack系列2
    MySQL源码之两阶段提交
  • 原文地址:https://www.cnblogs.com/lcezych/p/10986720.html
Copyright © 2020-2023  润新知