HDU 2899 Strange fuction

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2899

三分.第一次接触.首先要弄清楚函数的凹凸性.然后三分求最小/最大值.其取值在曲线顶点.

#include <iostream>
#include <cmath>
using namespace std;

//先求导函数,可知f'(x)=g'(x)+y,g'(x)为递增函数,
//1)若导函数最大值小于0,即g'(100)+y<0.则原函数在区间内单调递减.最小值为f(100).
//2)若导函数最小值大于0,即g'(0)=y>0,则原函数在区间内单调递增,最小值为f(0).
//3)若导函数有正有负,因导函数单调递增,所以必然从负值开始穿过x轴,导函数由负变正,原函数先减后增,其0点即原函数的最小值点.
//(或求二阶导数,在区间内,f''(x)>0,则原函数为凹函数,有最小值点.否则,为凸函数,有最大值点)
double f(double x,int y)
{
    return 6 * pow(x,7) + 8 * pow(x,6) + 7 * pow(x,3) + 5 * pow(x,2) - y * x; 
}

double g(double x,int y)
{
    return 42 * pow(x,6) + 48 * pow(x,5) + 21 * pow(x,2) + 10 * x - y;
}

int main(int argc, const char *argv[])
{
    int T;
    cin>>T;
    while(T--)
    {
        int Y;
        cin>>Y;
        if(g(100.0,Y)<0) printf("%.4lf\n",f(100,Y));
        else if(g(0.0,Y)>0) printf("%.4lf\n",f(0,Y));
        else
        {
            double low = 0 , heigh = 100.0;
            double mid ;
            while (heigh-low>1e-8)
            {
                mid = (low+heigh)/2;
                if(g(mid,Y)>0)
                {
                    heigh = mid;
                }else
                {
                    low = mid;
                }
            }

            printf("%.4lf\n",f(mid,Y));
        }
    }
    return 0;
}

 

 

posted @ 2013-09-22 17:15  Destino74  阅读(189)  评论(0编辑  收藏  举报