题外话-三分法
【模板】三分 (luogu P3382)
其实没什么好说的,直接套用三分模板就行了
直接上正确代码
View Code
#include <bits/stdc++.h>
using namespace std;
double evaluate(const vector<double>& coeffs, double x) {
double result = 0.0;
int degree = coeffs.size() - 1;
for (int i = 0; i < coeffs.size(); i++)
result += coeffs[i] * pow(x, degree - i);
return result;
}
int main() {
int n;
double l, r;
cin >> n >> l >> r;
// 读取多项式系数(从高次到低次)
vector<double> coeffs(n + 1);
for (int i = 0; i <= n; i++)
cin >> coeffs[i];
double eps = 1e-8;
while (r - l > eps) {
double mid1 = l + (r - l) / 3;
double mid2 = r - (r - l) / 3;
double f1 = evaluate(coeffs, mid1);
double f2 = evaluate(coeffs, mid2);
if (f1 < f2)
l = mid1;
else
r = mid2;
}
cout << fixed << setprecision(5) << (l + r) / 2 << "\n";
return 0;
}
然后,我又发现,题目给出的是多项式函数,且保证了在给出范围内为单峰以及单谷函数,这让我想到了求导
求导过后的函数是单调的,可以使用二分法求解
然后就写了篇相同思路的代码
View Code
#include <bits/stdc++.h>
using namespace std;
// 计算多项式在x处的值
// coeffs为系数向量,从高次到低次排列
double evaluate(const vector<double>& coeffs, double x) {
double result = 0.0;
int degree = coeffs.size() - 1; // 多项式次数 = 系数个数 - 1
for (int i = 0; i < coeffs.size(); i++)
result += coeffs[i] * pow(x, degree - i);
// coeffs[i] 对应 x^(degree-i) 项的系数
return result;
}
int main() {
int n;
double l, r;
cin >> n >> l >> r;
// 读取多项式系数(从高次到低次)
vector<double> coeffs(n + 1);
for (int i = 0; i <= n; i++)
cin >> coeffs[i];
// 计算导函数的系数
vector<double> deriv_coeffs;
for (int i = 0; i < n; i++)
// 原函数x^k的导数是k*x^(k-1),这里k = n - i
deriv_coeffs.push_back(coeffs[i] * (n - i));
// 二分法寻找导函数的零点(即原函数的极大值点)
double eps = 1e-8; // 精度控制,确保结果满足题目要求
while (r - l > eps) {
double mid = (l + r) / 2;
double deriv = evaluate(deriv_coeffs, mid);
if (deriv > 0)
// 导数为正,函数在mid处仍单调递增,极大值点在右侧
l = mid;
else
// 导数为负,函数在mid处已单调递减,极大值点在左侧
r = mid;
}
// 输出结果,保留5位小数
cout << fixed << setprecision(5) << (l + r) / 2 << "\n";
return 0;
}
这是评测记录

注意到第二种写法的内存占用更少


浙公网安备 33010602011771号