一本通 1.2 例 3【曲线】

题目link:https://loj.ac/problem/10013

经典的三分裸题。

三分主要是用来求一个满足单峰性的函数的最大/最小值的一种算法,其原理和二分基本一样。假设求最小值,首先把选择区域分为三段,然后比较这两个三等分点的函数值谁更小一些,大的那一边就不要了(如果大的是靠左的,那就连着左边不要了,靠右同理),容易证明这样做是正确的,然后像二分那样递归下去就可以得解。

这道题是裸题思路就没什么好说的了。

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int T, n, a[100010], b[100010], c[100010];
 5 double cal(double x)
 6 {
 7     double ans = -INF;
 8     for(int i = 1; i <= n; ++i) ans = max(ans, a[i] * x * x + b[i] * x + c[i]);
 9     return ans;
10 }
11 double half()
12 {
13     double ans = 0, l = 0, r = 1000;
14     for(int o = 1; o <= 100; ++o)
15     {
16         double mid1 = l + (r - l) / 3, mid2 = r - (r - l) / 3;
17         if(cal(mid1) < cal(mid2)) ans = mid1, r = mid2; else l = mid1;
18     }
19     return cal(ans);
20 }
21 int main()
22 {
23     scanf("%d", &T);
24     while(T--)
25     {
26         scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d %d %d", &a[i], &b[i], &c[i]);
27         printf("%.4lf\n", half());
28     }
29     return 0;
30 } 

 

posted @ 2020-11-03 20:03  louis_11  阅读(153)  评论(0)    收藏  举报