题目: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 ",f(100,Y)); else if(g(0.0,Y)>0) printf("%.4lf ",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 ",f(mid,Y)); } } return 0; }