【三分查找】Curves

【题目描述】

明明做作业的时候遇到了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;
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值