ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二分法的应用

2021-12-15 16:04:42  阅读:189  来源: 互联网

标签:lb int double mid bound 二分法 应用 ub


从一个有序数组中查找某个值

这是二分法最常用到的地方,也即折半查找法,在C++的STL库中有相关的lower_bound和upper_bound函数进行实现。

下面用代码块来实现STL中的lower_bound:

int n,k;//n为数组的大小,数组为a[0~n-1],k为要搜索的值
int a[MAX_N];

int Lower_bound()//找到满足ai>=k的最小的k值
{
    int lb=-1,ub=n;//初始化解的范围(lb,ub)
    
    while(ub-lb>1)//重复循环直到解的存在范围不大于一
    {
        int mid=(lb+ub)/2;
        
        if(a[mid]>=k)//如果mid满足条件,则解的范围变成(lb,mid]
        {
            ub=mid;
        }
        else //如果不满足,则解的范围变为(mid,ub]
        {
            lb=mid;
        }
    }
    
    //此时lb+1=ub,区间为(lb,ub],则ub为所求
    return ub;
}

该lower_bound算法也可拓展为求解满足某一个条件的最小值算法

=>推广:有N条绳子,长度为\(L_i\),从中切出长度相等的K段,求每段最长为多少。

int N,K;
double L[MAX_N];//输入

bool fit(double x)//判断该分割是否满足条件
{
    int num=0;
    for(int i=0;i<N;i++)
    {
        num=num+(int)(L[i]/x);
    }
    return num>=x;
}

double solve()
{
    double lb=0,ub=INF;//初始化解的范围(lb,ub)
    
    for(int i=0;i<100;i++)//此时相当于有ub-lb<1e-30
    {
        double mid=(lb+ub)/2;
        if(fit(mid)) lb=mid;//解的范围[mid,ub)
        else ub=mid;//解的范围(lb,mid]
    }
    return ub;//近似看作lb==ub
}

最大化最小值

将M个物品放在一条直线的N个位置,求使两两之间距离的最小值最大的值:

int N,M;
int x[MAX_N];//输入

bool fit(int d)//判断此时的d是否满足条件
{
    int last=0;
    for(int i=1;i<M;i++)
    {
        int crt=last+1;
        while(crt<N && x[crt]-x[last]<d)
        {
            crt++;
        }
        if(crt==N)return false;
        last=crt;
    }
    return true;
}

int solve()
{
    sort(x,x+N);//先对x数组排序
    
    int lb=0,ub=INF;//初始化解的范围(lb,ub);
    
   while(ub-lb>1)
   {
       int mid=(lb+ub)/2;
       if(fit(mid))lb=mid;//缩小为[mid,ub)
       else ub=mid;//缩小为[lb,mid)
   }
   return lb;
}

标签:lb,int,double,mid,bound,二分法,应用,ub
来源: https://www.cnblogs.com/LYX-Blogs/p/15693142.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有