Josephina is a clever girl and addicted to Machine Learning recently.
She pays much attention to a method called Linear Discriminant
Analysis, which has many interesting properties. In order to test the
algorithm’s efficiency, she collects many datasets. What’s more, each
data is divided into two parts: training data and test data. She gets
the parameters of the model on training data and test the model on
test data. To her surprise, she nds each dataset’s test error curve
is just a parabolic curve. A parabolic curve corresponds to a
quadratic function. In mathematics, a quadratic function is a
polynomial function of the form f ( x ) = ax 2
- bx
- c . The quadratic will degrade to linear function if a
= 0. It’s very easy to calculate the minimal error if there is only one test error curve. However, there are several datasets, which means
Josephina will obtain many parabolic curves. Josephina wants to get
the tuned parameters that make the best performance on all datasets.
So she should take all error curves into account, i.e., she has to
deal with many quadric functions and make a new error de nition to
represent the total error. Now, she focuses on the following new
function’s minimal which related to multiple quadric functions. The
new function F ( x ) is de ned as follow: F ( x ) = max( S i ( x )) ;
i
= 1 : : : n: The domain of x is [0 ; 1000]. S i ( x ) is a quadric function : Josephina wonders the minimum of F ( x ). Unfortunately,
it’s too hard for her to solve this problem. As a super programmer,
can you help her? Input The input contains multiple test cases. The
rst line is the number of cases T ( T < 100). Each case begins with a
number n ( n 10000). Following n lines, each line contains three
integers a (0 a 100), b ( j b j 5000), c ( j c j 5000), which
mean the corresponding coefficients of a quadratic function. Output
For each test case, output the answer in a line. Round to 4 digits
after the decimal point.
画图可以发现, F ( x ) F(x) F(x) 的图像是先增后减的,可以用三分法。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int t=300;
int n,a[10010],b[10010],c[10010];
double f(double x)
{
int i;
double ret=a[1]*x*x+b[1]*x+c[1];
for (i=2;i<=n;i++)
ret=max(ret,a[i]*x*x+b[i]*x+c[i]);
return ret;
}
int main()
{
int T,i;
double l,r,m1,m2;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
l=0;
r=1000;
for (i=1;i<=t;i++)
{
m1=(l*2+r)/3;
m2=(l+r*2)/3;
if (f(m1)<f(m2)) r=m2;
else l=m1;
}
printf("%.4f\n",f(l));
}
}