zoukankan      html  css  js  c++  java
  • 【数学】三分法

    Definition

    当一个函数(f(x))满足在区间在区间([l,r])内有且仅有一个(x~in~[l,r]~,~s.t.~~f(x))([l,x])内单调严格递增,在([x,r])内单调严格递减,则说(f(x))([l,r])内是一个单峰函数,求出单峰点(x)的算法为三分法。

    Solution

    考虑对一个区间([l,r]),取三等分点,记做(midl)(midr)。不妨设(midl~<~midr),则若(f(midl)~leq~f(midr)),则单峰点一定在区间([midl,r])范围内。反之单峰点一定在区间([l,midr])范围内。

    证明:

    首先设(f(midl)~<~f(midr))

    以下说明(midl)一定不在单峰点右侧。

    (midl)在单峰点右侧,则(forall~x_0~in~(midl,r]),都有(f(x_0)~<~f(x))。因为(midr~>~midl)(f(midr)~>~f(midl)),于是产生矛盾。故可说明(midl)一定不再单峰点右侧。

    (f(midl)~>~f(midr))时,证明同上。

    再设(f(midl)~=~f(midr))

    以下说明单峰点一定在([midl,midr])之间

    假设(midl)(midr)同在单峰点一侧,则(f(x))在区间([midl,midr])上严格单调,而(f(midl)~=~f(midr)),产生矛盾。于是单峰点一定在([midl,midr])之间。

    证毕

    于是在([l,r])内取两个三等分点(在代码中使用黄金分割点),比较两点函数值大小,对函数值较小的一侧缩小区间即可。

    Example

    传送门

    Description

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

    Input

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

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

    Output

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

    Hintt

    (forall:)

    (7~leq~n~leq~13~,~|A_i|~<10)。其中(|A_i|)为系数

    Solution

    板子题要啥solution

    Code

    #include<cmath>
    #include<cstdio>
    #define rg register
    #define ci const int
    #define cl const long long
    
    typedef long double ldb;
    typedef long long int ll;
    
    template <typename T>
    inline void qr(T &x) {
    	rg char ch=getchar(),lst=' ';
    	while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
    	while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	if(lst == '-') x=-x;
    }
    
    namespace IO {
    	char buf[120];
    }
    
    template <typename T>
    inline void qw(T x,const char aft,const bool pt) {
    	if(x < 0) {x=-x,putchar('-');}
    	rg int top=0;
    	do {IO::buf[++top]=x%10+'0';} while(x/=10);
    	while(top) putchar(IO::buf[top--]);
    	if(pt) putchar(aft);
    }
    
    inline void readldb(long double &x) {
    	double _temp;
    	scanf("%lf",&_temp);
    	x=_temp;
    }
    
    inline void printldb(const long double &x) {
    	double _ret=x;
    	printf("%.5lf
    ",_ret);
    }
    
    const int maxn = 20;
    const long double eps = 1e-10l;
    const long double mul = 0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374l;
    
    int n;
    ldb MU[maxn];
    
    ldb ask(ldb);
    
    int main() {
    	qr(n);
    	ldb l,r;readldb(l);readldb(r);
    	for(rg int i=0;i<=n;++i) readldb(MU[i]);
    	while((r-l) >= eps) {
    		ldb midl=r-(r-l)*mul,midr=l+(r-l)*mul;
    		ldb ansl=ask(midl),ansr=ask(midr);
    		if(ansl >= ansr) r=midr-eps;
    		else l=midl+eps;
    	}
    	printldb(l);
    	return 0;
    }
    
    ldb ask(ldb x) {
    	ldb _ret=0,_dx=1;
    	for(rg int i=n;~i;--i) _ret+=MU[i]*_dx,_dx*=x;
    	return _ret;
    }
    

    Summary

    当且仅当在单峰点两侧严格单调才能作为单峰函数处理

  • 相关阅读:
    LeetCode560. Subarray Sum Equals K
    各种排序算法C++
    MVC自定定义扩展点之ActionNameSelectorAttribute+ActionFilterAttribute 在浏览器中打开pdf文档
    [Asp.net Mvc]为js,css静态文件添加版本号
    Git 极简入门教程学习笔记
    LEFT JOIN与RIGHT JOIN学习笔记
    关于dm-file-uploader(dmUploader)上传时传参
    理解ASP.NET MVC引擎处理模型字符串的默认行为,涉及Html.Raw()和HttpUtility.HtmlDecode()
    HttpWebRequest(System.Net)模拟HTTP发送POST
    SQL Server分页模板
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/9991920.html
Copyright © 2011-2022 走看看