• Codeforces Round #514 (Div. 2) D. Nature Reserve 多个二次函数的最大值是三分函数的证明


    http://codeforces.com/contest/1059/problem/D

    最大值:

    最左下方和最右下方分别有一个点

    r^2 - (r-1)^2 = (10^7)^2

    maxr<0.5*10^14

    Way1:

    二分。

    difference:

    如果使用 5*10^13 -> 10^-6,2^ 60~70区间,pow,sqrt运算,实测超时。

    实际上是,使用

    time of a case:->

    Code:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+10;
     4 
     5 double x[maxn],y[maxn];
     6 double z=5.0*1e13;
     7 int n;
     8 
     9 bool work(double m)
    10 {
    11     double p,q,d;
    12     int i;
    13     p=-z; q=z;
    14     for (i=1;i<=n;i++)
    15     {
    16         d=sqrt(pow(m,2)-pow(m-y[i],2));
    17         p=max(p,x[i]-d);
    18         q=min(q,x[i]+d);
    19 //        if (p>q)
    20 //            return 0;
    21     }
    22 //    return 1;
    23     if (p<=q)
    24         return 1;
    25     else
    26         return 0;
    27 }
    28 
    29 int main()
    30 {
    31     double l=0,r,m;
    32     int v,i;
    33     scanf("%d",&n);
    34     v=0;
    35     for (i=1;i<=n;i++)
    36     {
    37         scanf("%lf%lf",&x[i],&y[i]);
    38         if (y[i]!=0)
    39         {
    40             if (v==0)
    41                 v=(y[i]>0);
    42             else if (v!=(y[i]>0))
    43             {
    44                 printf("-1");
    45                 return 0;
    46             }
    47         }
    48         y[i]=fabs(y[i]);
    49         l=max(l,y[i]/2);
    50     }
    51     r=z;
    52     while ((r-l)/max(1.0,l)>1e-6)
    53     {
    54         m=(l+r)/2;
    55         if (work(m))
    56             r=m;
    57         else
    58             l=m;
    59     }
    60     printf("%.10f",r);
    61     return 0;
    62 }

    Way2:

    多个二次函数f1,f2,…,fn,ax^2+bx+c (a>0)

    f(x)=max(f1(x),f2(x),…,fn(x)),

    而f是先减小,后增大,使用三分法

    证明:

    设f(x)是由多个连续的二次函数片段组成,相邻的二次函数片段的斜率逐渐增大,而每个二次函数片段都是f''>0,所以当前f''>0

    设加入新的函数后,变化的区间为

    1.[d1,d2],新的函数的片段替代原来的部分,满足f'‘’>0,且新的函数的片段往d1外,点外延伸,比原来的数值小,满足f'(d1-delta)<f'(d1+delta),f'(d2-delta)<f'(d2+delta)

    2.(-inf,d1],[d1,inf)同理。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define minv 1e-6
     5 #define inf 1e9
     6 #define pi 3.1415926536
     7 #define nl 2.7182818284
     8 const ll mod=1e9+7;//998244353
     9 const int maxn=1e5+10;
    10 
    11 int a[maxn],b[maxn],x[maxn],y[maxn],n;
    12 double u[maxn],v[maxn],w[maxn];
    13 
    14 double f(double m)
    15 {
    16     double mm,z=0;
    17     int i;
    18     mm=m*m;
    19     for (i=1;i<=n;i++)
    20         z=max(z,u[i]*mm+v[i]*m+w[i]);
    21     return z;
    22 }
    23 
    24 int main()
    25 {
    26     int cond=0,i;
    27     double l,r,m,mm,a,b;
    28     scanf("%d",&n);
    29     for (i=1;i<=n;i++)
    30     {
    31         scanf("%d%d",&x[i],&y[i]);
    32         if (y[i]!=0)
    33         {
    34             if (cond==0)
    35                 cond=(y[i]>0);
    36             else if (cond!=(y[i]>0))
    37             {
    38                 printf("-1");
    39                 return 0;
    40             }
    41         }
    42         y[i]=abs(y[i]);
    43         u[i]=0.5/y[i];
    44         v[i]=-1.0*x[i]/y[i];
    45         w[i]=(1.0*x[i]*x[i]+1.0*y[i]*y[i])/2/y[i];
    46     }
    47     l=-1.0e7,r=1.0e7;
    48     while (1)
    49     {
    50         m=(l+r)/2;
    51         mm=(m+r)/2;
    52         a=f(m);
    53         b=f(mm);
    54         if (fabs(a-b)/max(1.0,min(a,b))<1e-8)
    55             break;
    56         if (f(mm)>f(m))
    57             r=mm;
    58         else
    59             l=m;
    60     }
    61     printf("%.10f",a);
    62     return 0;
    63 }

    类似:

    hdu4717 The Moving Points

  • 相关阅读:
    Thrift中实现Java与Python的RPC互相调用
    Thrift介绍以及Java中使用Thrift实现RPC示例
    Netty中集成Protobuf实现Java对象数据传递
    ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化
    ProtoBuf在使用protoc进行编译时提示: Required fields are not allowed in proto3
    Netty中使用WebSocket实现服务端与客户端的长连接通信发送消息
    Netty中实现多客户端连接与通信-以实现聊天室群聊功能为例(附代码下载)
    Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
    Gradle项目在IDEA中运行时提示:Unnecessarily replacing a task that does not exist is not supported. Use create() or register() directly instead.
    Windows下curl的下载与使用
  • 原文地址:https://www.cnblogs.com/cmyg/p/9784683.html
Copyright © 2020-2023  润新知