题解:P1883 【模板】三分 | 函数
三分
学过三分的 dalao 可以直接去看思路。
众所周知,二分是在左右边界中折半查找。虽然这道题可以求导数再二分,但对于在上初中的本蒟蒻就不太友好了。QwQ
所以就有另一种十分友好的方法——三分。
所谓三分,本质上是找到两个中间点
此时,对于一个在
反之,如果
如果
一直重复以上过程,直到
思路
观察本题,发现是对函数
首先要确定
如果
但显然,虚线部分总是比实现部分大,则
直接进行三分即可。
代码
#include <bits/stdc++.h>
using namespace std;
int n, a[10005], b[10005], c[10005];
double f(double x) {
double y = INT_MIN;
for (int i = 1; i <= n; i++)
y = max(y, a[i] * x * x + b[i] * x + c[i]);
return y;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i] >> b[i] >> c[i];
double l = 0, r = 1000, m, e = 1e-9;
while (l + e < r) {
m = (l + r) / 2;
double u = m - e, v = m + e;
double fu = f(u), fv = f(v);
if (fu < fv)
r = m;
else if (fu > fv)
l = m;
else {
l = m;
r = m;
}
}
cout << fixed << setprecision(4) << f((l + r) / 2) << '\n';
}
return 0;
}
附言
由于精度问题,