zoukankan      html  css  js  c++  java
  • 二分法,三分法

    二分法

    二分法用来在有序数列中查找某个值是否存在

    但其实,二分最广泛的应用不是查找某个值,而是二分答案+check

    1.先将区间(左闭右开,不然可能会死循环)二分,每个区间的长度为1/2(right-left)

    2.如果mid能满足题目要求,那么使left变为mid+1,否则使right变为mid

    因为如果mid满足条件,那么[l,mid]区间肯定都满足条件,增大要求,否则减小要求

    bool check(int x){} // 检查是否可行 
    while(l<r)
    {
        int mid=(l+r)/2;
        if(check(mid)) l=mid+1;
        else r=mid;
    }

    最终答案为l-1

    分析一下最终答案是什么,由于只要能进if,则l等于满足条件的数+1,则最后二分出来的数值为最大的满足条件的数+1,即ans要-1

    最终二分出来的数值为

    若if那一行写的是l=mid+1,则数值为第一个能进不了if(条件)的数(即不满足条件),

    否则 若写的是r=mid,即为第一个能进得了if(条件)的数(即满足条件)

    三分法

    在区间内用两个mid将区间分成三份,这样的查找算法称为三分查找,也就是三分法,三分法常用于求解单峰函数的最值。  

    三分法和二分法有些类似,二分处理的是递增/减的函数,而三分处理的是先递增后递减(或相反)的函数(单峰函数)的最值

    1.先将区间三分,每个区间的长度为1/3(right-left)

    2.比较mid1和mid2的函数值谁大,如果mid1更大,right改为mid2,否则left改为mid1

    3.若区间长度小于5,特判避免死循环

    算法的正确性:
    1、lmid与rmid在最值的同一侧。由于单峰函数在最大值(最小值)任意一侧都具有单调性,因此,lmid与rmid中,更大(小)的那个数自然更为靠近最值。此时,我们远离最值的那个区间不可能包含最值,因此可以舍弃。
    2、lmid与rmid在最值的两侧。由于最值在中间的一个区间,因此我们舍弃一个区间后,并不会影响到最值
    int ans=-1;
    int f(int x){}//求函数值 
    while(1)
    {
        if(r-l<5)
        {
            for(int i=l;i<=r;i++)ans=max(ans,f(i));
            break;
        }
        int lm=l+(r-l)/3,rm=r-(r-l)/3;
        if(f(lm)<f(rm))l=lm;
        else r=rm;
    } 

    最终答案为ans

  • 相关阅读:
    collect_mesh_vertexs input_poly
    模型变形第一版 (模型包裹)
    模型变形第一版,(射线完成)
    对于法线包裹的 操作方法, 觉得用mesh 的点的法线方向,比poly的法线方向好使。
    gt_2_collect_mesh_vertexs
    好的写法 数组唯一化, 这个是多么的简单,。
    模型变形第一版(模型变形)
    include 使用形式
    MySQL用户权限管理
    mysql load data infile的使用
  • 原文地址:https://www.cnblogs.com/lher/p/7481554.html
Copyright © 2011-2022 走看看