【三分查找】Curves

来源:互联网 发布:淘宝篮球鞋正品店推荐 编辑:程序博客网 时间:2024/05/21 15:38

【题目描述】

明明做作业的时候遇到了n个二次函数Si(x)= ax2 + bx + c,他突发奇想设计了一个新的函数F(x) = max(Si(x)), i = 1...n.

明明现在想求这个函数在[0,1000]的最小值,要求精确到小数点后四位四舍五入。

【输入数据】

输入包含T 组数据 (T < 10) ,每组第一行一个整数 n(n ≤ 10000) ,之后n行,每行3个整数a (0 ≤ a ≤ 100), b (|b| ≤ 5000), c (|c| ≤ 5000) ,用来表示每个二次函数的3个系数,注意二次函数有可能退化成一次。

【输出数据】

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

【样例输入】

2

1

2 0 0

2

2 0 0

2 -4 2

【样例输出】

0.0000

0.5000

【数据范围】

T < 10, n ≤ 10000 , 0 ≤ a ≤ 100,|b| ≤ 5000, |c| ≤ 5000

前50%数据n ≤ 100

【分析】

因为本题模型是一个凸函数而不一定有单调性,所以要三分答案。

关于三分:http://blog.csdn.net/wzy_1988/article/details/9075963

【代码】

#include<iostream>#include<cstdio>using namespace std;double ji=1e-9;int n,a[10010],b[10010],c[10010];void init(){scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d%d%d",&a[i],&b[i],&c[i]);return;}double fi(double x){double re=a[1]*x*x+b[1]*x+c[1];for (int i=2;i<=n;i++) re=max(re,(double)a[i]*x*x+b[i]*x+c[i]);return re;}void work(){double l=0,r=1000;double lm,rm;while (r-l>ji){lm=l+(r-l)/3.0;rm=r-(r-l)/3.0;    if (fi(lm)>fi(rm)) l=lm;    else r=rm;}printf("%.4lf\n",fi(l));return;}int main(){freopen("curves.in","r",stdin);freopen("curves.out","w",stdout);int t;scanf("%d",&t);for (int i=1;i<=t;i++){init();    work();}return 0;}



原创粉丝点击