二分法

整数集合上的二分

假设函数 check(x)(xZ)\text{check}(x)(x\in \mathbb{Z}) 满足存在一个整数 ll,使得 [i<l,check(i)=0][il,check(i)=1][\forall i<l,check(i)=0]\land[\forall i\ge l,check(i)=1]

  • 求一个最小的 xx,使 check(x)=1check(x)=1
while(l<r)
{
    int mid=(l+r)>>1;
    if(check(mid))
        r=mid;
    else
        l=mid+1;
}
  • 求一个最大的 xx,使 check(x1)=0check(x-1)=0
while(l<r)
{
    int mid=(l+r+1)>>1;//必须+1
    if(check(mid))
        l=mid;
    else
        r=mid-1;
}

实数域上的二分

假设函数 check(x)(xR)\text{check}(x)(x\in \mathbb{R}) 满足存在一个实数 rr,使得 [i<r,check(i)=0][ir,check(i)=1][\forall i<r,check(i)=0]\land[\forall i\ge r,check(i)=1]

接下来两个方法都是求上面的 rr

  • 以精度 epseps 为条件,一般需要保留 kk 位小数时,取 eps=10(k+2)eps=10^{-(k+2)};表达式一般为 [l+eps<r][l+eps<r]
while(l+eps<r)
{
    double mid=(l+r)/2;
    if(check(mid))
        r=mid;
    else
        l=mid;
}
  • 精度不适合表示或确定时,采用固定循环次数的二分方法,这种方法得到的结果的精度更高。
for(int i=1;i<=100;i++)
{
    double mid=(l+r)/2;
    if(check(mid))
        r=mid;
    else
        l=mid;
}
posted @ 2022-02-21 17:08  luckydrawbox  阅读(5)  评论(0)    收藏  举报  来源