• 【模板】三分法


    对比于二分法,三分法的适用范围要略窄一些,但是并不是代表它没有用,在一些题目中还是有很大用处的。。。

    三分法是用来求一个凸性函数的方法,所谓凸性函数就是一个函数在某一区间内有最大值,最大值两侧各具有单调性,并且单调性相反。

    题目大意:

    给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减。试求出x的值

    输入格式:

    第一行一次包含一个正整数N和两个实数l、r,含义如题目描述所示

    第二行包含N+1个实数,从高到低依次表示该N次函数各项的系数

    输出格式:

    输出为一行,包含一个实数,即为x的值。四舍五入保留5位小数。

    首先,我们先求出l和r的中点mid,再求出mid和r的中点midd,分别将mid和midd代入式子,判断那个值大,舍弃值小的一段区间[l,mid]或[midd,r],然后接着三分直到找到答案为止。正确性还是比较显然的,如果mid与midd同侧,那么显然大的值更靠近x,如果异侧也是同理的(当然我们是无法知道同侧还是异侧的。。。)

    最后,附上本题代码:

     1 #include<cstdio>
     2 #define maxn 13
     3 using namespace std;
     4 
     5 const double eps=1e-8;
     6 int n;
     7 double a[maxn+5];
     8 double l,r;
     9 
    10 double check(double x)
    11 {
    12     double ans=a[n+1];
    13     for(int i=n; i>=1; i--)
    14     {
    15         double temp=a[n-i+1];
    16         for(int j=1; j<=i; j++)
    17         {
    18             temp*=x;
    19         }
    20         ans+=temp;
    21     }
    22     return ans;
    23 }
    24 int main()
    25 {
    26     scanf("%d%lf%lf",&n,&l,&r);
    27     for(int i=1; i<=n+1; i++)
    28     {
    29         scanf("%lf",&a[i]);
    30     }
    31     while(r-l>eps)
    32     {
    33         double mid=(r+l)/2,midd=(mid+r)/2;
    34         if(check(mid)>check(midd))
    35         {
    36             r=midd;
    37         }
    38         else
    39         {
    40             l=mid;
    41         }
    42     }
    43     printf("%.5lf",l);
    44     return 0;
    45 }
  • 相关阅读:
    SPI masterslave驱动框架分析
    linux内存分配方法总结
    C#图片适应PictureBox大小显示
    .NET下的AO对象的安全释放
    .net C# PropertyGrid 显示下拉列表
    Oracle事务细节问题
    C#中Remoting的IPC通信之Winform与Windows服务通信错误问题及解决
    windows服务的安装与卸载
    windows环境下Oracle数据库冷备份和恢复全过程
    OGR连接数据源读取矢量数据图层(C#)
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10582037.html
Copyright © 2020-2023  润新知