算法笔记--三分查找

好菜啊,现在才学三分。

三分:查找凸形(凹形)函数的极大值(极小值)。

模板1:

double three_divide()
{
    double l=0,r=1000;
    double mid=(l+r)/2;
    double mm=(l+mid)/2; 
    while(r-l>=eps)
    {
        if(F(mid)>F(mm))r=mid;
        else l=mm;
        mid=(l+r)/2;
        mm=(l+mid)/2;
    }
    return F(mid);
}

模板2:

double three_divide()
{
    double l=0,r=1000;
    double m1=(l+l+r)/3;
    double m2=(l+r+r)/3; 
    while(r-l>=eps)
    {
        if(F(m2)>F(m1))r=m2;
        else l=m1;
        m1=(l+l+r)/3;
        m2=(l+r+r)/3;
    }
    return F(m1);
}

例题1:HDU 3714 Error Curves

代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const double eps=1e-9;
const int N=1e4+5;
struct node
{
    double a,b,c;
}x[N];
int n;

double F(double t)
{
    double ans=t*t*x[0].a+t*x[0].b+x[0].c;
    for(int i=1;i<n;i++)
    ans=max(ans,t*t*x[i].a+t*x[i].b+x[i].c);
    return ans;
}
double three_divide()
{
    double l=0,r=1000;
    double m1=(l+l+r)/3;
    double m2=(l+r+r)/3; 
    while(r-l>=eps)
    {
        if(F(m2)>F(m1))r=m2;
        else l=m1;
        m1=(l+l+r)/3;
        m2=(l+r+r)/3;
    }
    return F(m1);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        double ans=-0x3f3f3f3f;
        cin>>n;
        for(int i=0;i<n;i++)cin>>x[i].a>>x[i].b>>x[i].c;
        ans=three_divide();
        cout<<fixed<<setprecision(4)<<ans<<endl;
    } 
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/7615938.html