欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > P1883 【模板】三分 | 函数

P1883 【模板】三分 | 函数

2025/5/16 13:21:42 来源:https://blog.csdn.net/Ct314/article/details/147015761  浏览:    关键词:P1883 【模板】三分 | 函数

题目描述

给定 n 个二次函数 f1​(x),f2​(x),…,fn​(x)(均形如 ax2+bx+c),设 F(x)=max{f1​(x),f2​(x),...,fn​(x)},求 F(x) 在区间 [0,1000] 上的最小值。

输入格式

输入第一行为正整数 T,表示有 T 组数据。

每组数据第一行一个正整数 n,接着 n 行,每行 3 个整数 a,b,c,用来表示每个二次函数的 3 个系数,注意二次函数有可能退化成一次。

输出格式

每组数据输出一行,表示 F(x) 的在区间 [0,1000] 上的最小值。答案精确到小数点后四位,四舍五入。

说明/提示

对于 50% 的数据,n≤100。

对于 100% 的数据,T<10, n≤104,0≤a≤100,∣b∣≤5×103,∣c∣≤5×103。

#include <bits/stdc++.h>
using namespace std;const int MAXN = 100005;
int a[MAXN], b[MAXN], c[MAXN];
int n;double F(double x) {double res = -1e18;for (int i = 0; i < n; i++) {res = max(res, a[i]*x*x + b[i]*x + c[i]);}return res;
}int main() {int T;cin >> T;while (T--) {cin >> n;for (int i = 0; i < n; i++) {cin >> a[i] >> b[i] >> c[i];}double l = 0.0, r = 1000.0;while (r - l > 1e-9) {  // 保证精度double lmid = l + (r - l) / 3;double rmid = r - (r - l) / 3;if (F(lmid) < F(rmid))r = rmid;elsel = lmid;}printf("%.4f\n", F(l));}return 0;
}

F(x) 表示:在每个 x 位置上,取所有函数中值最大的那一个

由于 a≥0,每个函数是凹的。它们的最大值组成的函数F(x)还是凹的

F(x) 先下降、后上升

三分法的思路是:

  • 找出两个三分点 lmid, rmid

  • 比较 F(lmid) 和 F(rmid)

  • 因为 F(x) 是凹函数(先降后升),

    • 如果 F(lmid) < F(rmid),说明最小值在左侧

    • 否则在右侧

  • 不断缩小区间 lr

直到区间极小(小于 10^-9),我们认为找到了极小值点。

由于浮点数存在精度问题,当进行多次计算时,会有非常微小的误差。如果使用 l <= r,在接近正确解的时候,lr 可能永远不完全相等,所以会陷入死循环。

  • 精度终止条件:使用 r - l > epsilon(比如 1e-9)可以确保在精度范围内停止,不依赖于 lr 是否恰好相等。只要它们之间的差距小到几乎无法再缩小,就认为已经找到了最优解

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词