zoukankan      html  css  js  c++  java
  • 洛谷 P3382 【模板】三分法

    洛谷 P3382 【模板】三分法

    思路

    这是一道三分的模板题
    用于求单峰函数的极值

    首先,在函数上标4个点:(x=l,r,mid,mmid)。其中(mmid)(mid)(r)的中点。(其实就是把函数三等分了)

    然后我们需要通过迭代来缩小范围((while)循环)

    如果(f(mid)>f(mmid)),则(mmid)一定在峰的右边。
    如果(f(mid)<f(mmid)),则(mid)一定在峰的左边。

    证明:
    1.我们假设存在(f(mid)>f(mmid))(mmid)在峰的左边。
    由于(f(x))在峰的左边单调递增,且(f(mid)>f(mmid)),所以(mid)(mmid)的右边。
    然而(mmid = frac{mid+rt}{2}),显然(mid)(mmid)左边。矛盾。

    2.我们假设存在(f(mid)<f(mmid))(mid)在峰的右边。
    由于(f(x))在峰的右边单调递减,且(f(mid)<f(mmid)),所以(mid)(mmid)的右边。
    然而(mmid = frac{mid+rt}{2}),显然(mid)(mmid)左边。矛盾。

    那么如何求(f(n))

    这就需要用到秦九韶公式了,大家可以自行百度,这里就不说了

    让我帮帮你吧

    代码

    #include<bits/stdc++.h>
    #define db double
    #define N 20
    using namespace std;
    
    const db eps=1e-6;
    int n;
    db a[20],l,r,mid,mmid,k;
    
    db f(db x){
    	db s=0;
    	for(int i=0;i<=n;i++)s=s*x+a[i];//秦九韶公式,自行百度 
    	return s; 
    }
    
    int main(){
    	scanf("%d%lf%lf",&n,&l,&r);
    	for(int i=0;i<=n;i++){
    		scanf("%lf",&a[i]);
    	}
    	while(r-l>=eps){
    		k=(r-l)/3.0;
    		mid=l+k;
    		mmid=r-k;
    		if(f(mid)>f(mmid))r=mmid;
    		else l=mid;
    	}
    	printf("%.5lf
    ",l);
    	return 0;
    }
    
  • 相关阅读:
    链式栈的C++实现
    Java面试之设计模式二
    前端资源
    Java面试之异常
    Java面试之序列化
    Java面试之重写(Override)与重载(Overload)
    项目视图展示
    Java面试之集合
    Java面试之SSH框架面试题集锦
    JDBC技术
  • 原文地址:https://www.cnblogs.com/loceaner/p/10904418.html
Copyright © 2011-2022 走看看