BYRBT

HDU 2899 Strange fuction——分治+数学

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

 

Strange fuction

Problem Description
Now, here is a fuction:
  F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)
Can you find the minimum value when x is between 0 and 100.
 

 

Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)
 

 

Output
Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.
 

 

Sample Input
2 100 200
 

 

Sample Output
-74.4291 -178.8534
 

 

Author
Redow
 

 

Recommend
lcy
 
题解:
  题目意思就是求题目中的目标函数的在[0,100]内的最小值。
 
  次数太高了,怎么办???
 
  求个导:f(x)'=42*x^6+48*x^5+21*x^2+10*x-y,这样就把y与x分开来了,而这东西在[0,100]上是单增的(显而易见),既然具有单调性,二分答案即可了。
 
  但还有另一个做法,我们求导之后发现它的导函数在该区间上是单调的,那么从另外一个角度来说,原函数在该区间上是有凸性的,对于一格有凸性的的函数求最值,我们就可以用三分来做了。
 
  这道题即可以用来练二分又可以练三分,还能练数学,虽然是道水题,却不失为道好题………………
 
View Code
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 
 7 using namespace std;
 8 
 9 double get(double x,double y)
10 {
11     return 6.0*x*x*x*x*x*x*x+8.0*x*x*x*x*x*x+7.0*x*x*x+5.0*x*x-y*x;
12 }
13 
14 double get2(double x,double y)
15 {
16     return 42.0*x*x*x*x*x*x+48.0*x*x*x*x*x+21.0*x*x+10.0*x-y;
17 }
18 
19 void way1()
20 {
21     int t;
22     scanf("%d",&t);
23     for (int a=1;a<=t;a++)
24     {
25         double y;
26         scanf("%lf",&y);
27         double r=100.0,l=0.0;
28         while (r-l>=1e-6)
29         {
30             double lm=(r-l)/3.0+l;
31             double rm=r-lm+l;
32             if (get(lm,y)<get(rm,y)) r=rm;
33             else l=lm;
34         }
35         printf("%.4lf\n",get(r,y));
36     }
37 }
38 
39 void way2()
40 {
41     int t;
42     scanf("%d",&t);
43     for (int a=1;a<=t;a++)
44     {
45         double y;
46         scanf("%lf",&y);
47         double r=100.0,l=0.0;
48         while (r-l>=1e-6)
49         {
50             double m=(l+r)/2.0;
51             if (get2(m,y)<0) l=m;
52             else r=m;
53         }
54         printf("%.4lf\n",get(r,y));
55     }
56 }
57 
58 int main()
59 {
60     //way1();//三分
61     way2();//求导二分
62 
63     return 0;
64 }

 

posted @ 2012-05-09 23:04  zhonghaoxi  阅读(264)  评论(2)    收藏  举报
BYRBT