hdoj3714【三分】

手动插姿势:
三分法可以应用于凸函数或者凹函数的求极值。
三分讲解:http://blog.csdn.net/pi9nc/article/details/9666627
三分模板:http://www.cnblogs.com/Hilda/archive/2013/03/02/2939708.html

double cal(Type a)
{
    /* 根据题目的意思计算 */
}

void solve()
{
    double Left, Right;
    double mid, midmid;
    double mid_value, midmid_value;
    Left = MIN; Right = MAX;
    while (Left + EPS <= Right)
    {
        mid = (Left + Right) / 2;
        midmid = (mid + Right) / 2;
        if (cal(mid)>=cal(midmid)) 

            Right = midmid;
        else Left = mid;
    }
}
更多相关题:
HDU :3400  2298  4454  2438  3756  
POJ: 3301 3737  
ZOJ: 3203

题意:
给n个二次函数,定义域为[0,1000], 求x在定义域中每个x所在的n个函数的最大值的最小值。
思路:
其实说N个函数的话,定义域也确定了,要么是单调增,要么是单调减,要么就是凹性,因为a>=0的,三分一下,每次找位置的最大,然后取最小就好了。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int N=1e4;
const double eps=1e-9;
const double INF=1e15;

struct asd{
    double a,b,c;
};
asd q[N];
int n;

double fx(double a,double b,double c,double x)
{
    return a*x*x+b*x+c;
}

double getmin(double x)
{
    double temp;
    double ans=-INF;
    for(int i=0;i<n;i++)
    {
        temp=fx(q[i].a,q[i].b,q[i].c,x);
        if(ans<temp)
            ans=temp;
    }
    return ans;
}

void sanfen()
{
    double ans=INF;
    double Left, Right;
    double mid;
    double temp1,temp2;
    Left = 0; Right = 1000;

    while (Left<=Right)
    {
        mid=(Left+Right)/2;
        temp1=getmin(mid);
        temp2=getmin(mid-eps);
        if(temp1<temp2)
            Left=mid+eps;
        else
            Right=mid-eps;
        if(ans>temp1)
            ans=temp1;
    }
    printf("%.4lf
",ans);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf%lf",&q[i].a,&q[i].b,&q[i].c);

        sanfen();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934805.html