【hdu5105】求极值

http://acm.hdu.edu.cn/showproblem.php?pid=5105

直接暴力解,解法是先确定一个粗糙的精度,枚举x,若发现了极值点,则用二分得出精确结果来更新答案。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <map>
 7 #include <vector>
 8 #include <stack>
 9 #include <string>
10 #include <ctime>
11 #include <queue>
12 #define mem0(a) memset(a, 0, sizeof(a))
13 #define mem(a, b) memset(a, b, sizeof(a))
14 #define lson l, m, rt << 1
15 #define rson m + 1, r, rt << 1 | 1
16 #define eps 0.0000001
17 #define lowbit(x) ((x) & -(x))
18 #define memc(a, b) memcpy(a, b, sizeof(b))
19 #define x_x(a) ((a) * (a))
20 #define LL long long
21 #define DB double
22 #define pi 3.14159265359
23 #define MD 10000007
24 #define eps 0.000001
25 #define max(a, b) ((a) > (b)? (a) : (b))
26 using namespace std;
27 double cc = 10000.0;
28 double a[5], ans;
29 double calc(double x)
30 {
31         double ans = 0;
32         for(int i = 1; i <= 4; i++) {
33                 ans = ans * x + a[i];
34         }
35         return fabs(ans);
36 }
37 void solve(double L, double R)
38 {
39         double l = L, r = R, fl = calc(l), fr = calc(r);
40         while(r - l > eps) {
41                 double m1 = l + (r - l) / 3, m2 = r - (r - l) / 3;
42                 double fm1 = calc(m1), fm2 = calc(m2);
43                 if(fm1 < fm2) {
44                         l = m1;
45                         fl = fm1;
46                 }
47                 else {
48                         r = m2;
49                         fr = fm2;
50                 }
51         }
52         ans = max(ans, calc(l));
53 }
54 int main()
55 {
56         //freopen("input.txt", "r", stdin);
57         while(1) {
58                 ans = 0;
59                 for(int i = 1; i <= 4; i++) {
60                         if(!(cin>> a[i])) return 0;
61                 }
62                 double L, R;
63                 cin>> L>> R;
64                 double tmp = (R - L) / cc, f, f1 = 0, f2 = 0;
65                 for(int i = 0; i <= cc; i++) {
66                         double x = L + (double)i * tmp;
67                         f = calc(x);
68                         ans = max(ans, f);
69                         if(f < f1 && f2 < f1) solve(max(L, x - 2 * tmp), x);
70                         f2 = f1;
71                         f1 = f;
72                 }
73                 printf("%.2f\n", ans);
74         }
75         return 0;
76 }
View Code

另一种方法:

f(x)=|ax3+bx2+cx+d|, 求最大值。令g(x)=ax3+bx2+cx+d,f(x)的最大值即为g(x)的正最大值,或者是负最小值。a!=0时,g(x)=3ax2+2bx+c ,

求出g(x)的根(若存在,x1,x2,由导数的性质知零点处有极值。ans=max(f(xi)|LxiR).然后考虑两个端点的特殊性有ans=max(ans,f(L),f(R)).

 

posted @ 2014-11-21 18:24  jklongint  阅读(101)  评论(0)    收藏  举报