bzoj 4570 妖怪

bzoj 4570 妖怪

  • 正解应该是 \(O(nlogn)\) 的凸包,但被我的 \(O(100n)\) 的三分水过去了.
  • 记 $x=\frac b a $ ,显然有 \(strength_i=ATK_i+DFN_i+ATK_i\ \cdot\ x+DFN_i\ \cdot\ \frac 1 x\).
  • 每个\(strength\) 关于 \(x\) 是一个单峰函数,取最大值形成的函数也是一个单峰函数,三分 \(x\) 即可.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
    int x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
const double eps=1e-9;
const int T=100;
int dcmp(double x)
{
    return fabs(x)<eps?0:(x>0?1:-1);
}
double Max(double a,double b)
{
    return dcmp(a-b)>=0?a:b;
}
double Min(double a,double b)
{
    return dcmp(a-b)>=0?b:a;
}
const int MAXN=1e6+10;
int n;
double p[MAXN],q[MAXN];
double ans=1e18;
double calc(double x)
{
    double res=0;
    for(int i=1;i<=n;++i)
        {
            double str=p[i]+q[i]+p[i]*x+q[i]/x;
            res=Max(res,str);
        }
    return res;
}
double mx=0;
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
        {
            scanf("%lf%lf",&p[i],&q[i]);
            mx=Max(mx,q[i]);
        }
    double L=eps*1000,R=1e8;
    for(int t=1;t<=T;++t)
        {
            double x1=L+(R-L)/3;
            double x2=R-(R-L)/3;
            double f1=calc(x1);
            double f2=calc(x2);
            if(dcmp(f1-f2)>=0)
                {
                    ans=Min(ans,f2);
                    L=x1;
                }
            else
                {
                    ans=Min(ans,f1);
                    R=x2;
                }
        }
    printf("%.4lf\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/jklover/p/10388848.html