【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 }
另一种方法:
f(x)=|a∗x3+b∗x2+c∗x+d|, 求最大值。令g(x)=a∗x3+b∗x2+c∗x+d,f(x)的最大值即为g(x)的正最大值,或者是负最小值。a!=0时,g′(x)=3∗a∗x2+2∗b∗x+c ,
求出g′(x)的根(若存在,x1,x2,由导数的性质知零点处有极值。ans=max(f(xi)|L≤xi≤R).然后考虑两个端点的特殊性有ans=max(ans,f(L),f(R)).

浙公网安备 33010602011771号