二分&三分

二分比较的熟悉了,这里就指出ta的必要条件:

  • 答案具有单调性
  • 已知答案的情况下,可以判定答案的可行性
我们的重点是三分

如果说二分针对的是单调函数,那么三分针对的是双调函数
比如求点到椭圆的最近距离的题目,就可以通过三分一次次的逼近

双调函数也就是下面这样的函数
这里写图片描述
具体步骤和二分大同小异:

  • f(M1)<f(M2) f ( M 1 ) < f ( M 2 ) 的时候,我们可以断定 M1 M 1 一定在最高点(蓝点)的左边
    反证法:
    假设 M1 M 1 在白点的右边,则 M2 M 2 也一定在白点的右边
    又由 f(M1)<f(M2) f ( M 1 ) < f ( M 2 ) 可推出 M1>M2 M 1 > M 2 ,与已知矛盾,故假设不成立
    此时可以将 l=M1 l = M 1 来缩小范围
  • f(M1)>f(M2) f ( M 1 ) > f ( M 2 ) 的时候,我们可以断定 M2 M 2 一定在蓝点的右边
    反证法:
    假设 M2 M 2 在白点的左边,则 M1 M 1 也一定在白点的左边
    又由 f(M1)>f(M2) f ( M 1 ) > f ( M 2 ) 可推出 M2<M1 M 2 < M 1 ,与已知矛盾,故假设不成立
    此时可以将 r=M2 r = M 2 来缩小范围。

在具体实现的时候有两种方法:

int three_divide(int l,int r)
{
    while (l<r-1)
    {
        int mid=(l+r)>>1;
        int mmid=(mid+r)>>1;
        if (f(mid)>f(mmid))
            r=mmid;
        else l=mid;
    }
    return f(l)>f(r)? l:r;
}
double three_divide(double l,double r)
{
    double m1,m2;
    while (r-l>=eps)
    {
        m1=l+(r-l)/3;
        mr=r-(r-l)/3;
        if (f(m1)>f(m2))
            r=m2;
        else l=m1;
    }
    return (m1+m2)/2;
}

下面是下凸函数的三分查询:
这里写图片描述

int three_divide(int l,int r)
{
    while (l<r-1)
    {
        int mid=(l+r)>>1;
        int mmid=(mid+r)>>1;
        if (f(mid)>f(mmid))
           l=mid;
        else r=mmid;
    }
    return f(l)>f(r)? r:l;
}
double three_divide(double l,double r)
{
    double m1,m2;
    while (r-l>=eps)
    {
        m1=l+(r-l)/3;
        m2=r-(r-l)/3;
        if (f(m1)>f(m2))
           l=m1;
        else r=m2;
    }
    return (m1+m2)/2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值