梯度下降可过
  • 板块P1883 函数
  • 楼主GoodCoder666
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/6/15 19:54
  • 上次更新2024/6/15 21:47:57
查看原帖
梯度下降可过
324562
GoodCoder666楼主2024/6/15 19:54

rt,136ms136\mathrm{ms} 最优解第一页(还有优化空间)。欢迎 hack。

#include <cstdio>
#define maxn 10005
#define EPS 1e-12
using namespace std;

int n, a[maxn], b[maxn], c[maxn];

inline double eval(int i, double x) { return a[i] * x * x + b[i] * x + c[i]; }
inline double diff(int i, double x) { return 2 * a[i] * x + b[i]; }
inline int argmax(double x)
{
    int best = 0;
    double best_val = eval(0, x);
    for(int i=1; i<n; i++)
    {
        double cur = eval(i, x);
        if(cur > best_val)
            best_val = cur, best = i;
    }
    return best;
}

const double l = 0, r = 1000;

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i=0; i<n; i++)
            scanf("%d%d%d", a + i, b + i, c + i);
        double x = (l + r) * 0.5;
        double lr = 1.0;
        int am = argmax(x);
        while(lr > EPS)
        {
            double nx = x - lr * diff(am, x);
            if(nx < l || nx > r) lr *= 0.8;
            else
            {
                int nm = argmax(nx);
                if(eval(nm, nx) < eval(am, x))
                    am = nm, x = nx, lr *= 1.1;
                else lr *= 0.5;
            }
        }
        printf("%.4lf\n", eval(am, x));
    }
    return 0;
}
2024/6/15 19:54
加载中...