P1883 函数

菜鸡面对大数据范围瑟瑟发抖。。。

我本来看到这道题有多个数据点,然后预处理一个函数就差不多快超时了,还以为不可做呢。。。

看来其实是我太菜了。。。


有个很重要的东西:

这道题中\(0 \leq a \leq 100\)

说明当这个函数是二次的时候一定是开口向上的!

大概可以发现:我们要求的这个\(F(x)\)是一个下凸的函数,而我们要求的就是这个最小值所在的函数值

面对这些单峰的函数,我们直接使用三分法就可以求解了。三分法也挺简单的,就不讲了。

为什么上面有粗体字呢?因为这个样例很坑,没有帮你纠正这个错误!

所以最后记得输出函数值而不是相应的x就可以了。

代码:

#include<cstdio>
#include<algorithm>
#define ll long long
const int maxn = 10005;
const double eps = 1e-10;
struct Nodes
{
    ll a, b, c;
} s[maxn];

ll n;
double F(double x)
{
    double ans = -9999999999;
    for(int i = 1; i <= n; i++) ans = std::max(ans, s[i].a * x * x + s[i].b * x + s[i].c);
    return ans;
}
void init()
{
    
}
ll read()
{
    ll ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
    return s * ans;
}
int main()
{
    int T = read();
    while(T--)
    {
        init();
        n = read();
        for(int i = 1; i <= n; i++) s[i].a = read(), s[i].b = read(), s[i].c = read();
        double l = 0, r = 1000;
        for(int i = 1; i <= 100; i++)
        {
            double mid = (l + r) / 2;
            if(F(mid - eps) < F(mid + eps)) r = mid + eps;
            else l = mid - eps;
        }
        printf("%.4lf\n", F(l));
    }
    return 0;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9813572.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值