题目: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.
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 }