二分算法

三分板子

先看求导二分

\[slope=\frac{y_1-y_2}{x_1-x_2}导函数为f^{′}(x)=lim_{\Delta x→0}\frac{f(x+\Delta x)-f(x)}{\Delta x} \]

double derivative(double x){
	double dx = 1e-10;
	double dy = f(x+dx)-f(x);
	return dy/dx;
}

在凸函数寻找唯一导数0点,所以可以二分

秦九韶算法求n次多项式

\[f(x)=a_nx^n+a_{n-1}x^{n-1}+...+a_1x+a_0;\\ f(x)=(a_nx^{n}+a_{n-1}x^{n-2}+..a_2x+a_1)x+a_0\\ =((a_nx^{n-2}+a_{n-1}x^{n-3}+...a_3x+a_2)x+a_1)x+a_0\\ 令k_1=a_n*x+a_{n-1}\\ k_2=k_1x+a_{n-2}\\k_n=k_{n-1}x+a_0 \]

#include<bits/stdc++.h>
#define eps 1e-10
using namespace std;
double l,r,a[20];
int n;
double f(double x){
	double sum = a[n];
	for(int i = n-1;i >= 0;i--)
	sum = sum * x + a[i];
	return sum;
}
double check(double x){
	double dx = eps;
	double dy = f(x + dx) - f(x);
	return dy/dx;
}
int main(){
	 scanf("%d",&n);
    scanf("%lf%lf",&l,&r);
    for(int i=0;i<=n;++i)
        scanf("%lf",&a[n-i]);
    double mid;    
    while(r-l > eps){
        mid = (l+r)/2;
        if(check(mid) > 0) l = mid;
        else r = mid;
    }    
    printf("%.5lf",mid);
    return 0;    
}

三分

#include<bits/stdc++.h>
#define eps 1e-6
using namespace std;
double l,r,a[20];
int n;
double f(double x){
	double sum = a[n];
	for(int i = n-1;i >= 0;i--)
	sum = sum * x + a[i];
	return sum;
}
double check(double x){
	double dx = eps;
	double dy = f(x + dx) - f(x);
	return dy/dx;
}
double find(double l,double r){
	double lmid,rmid;
	while(l + eps <= r){
		lmid = l + (r-l)/3.0;
		rmid = r - (r-l)/3.0;
		if(f(lmid) < f(rmid)) l = lmid;
		else r = rmid;
	}
	return (lmid + rmid)/2.0;
}
int main(){
	scanf("%d",&n);
    scanf("%lf%lf",&l,&r);
    for(int i=0;i<=n;++i)
        scanf("%lf",&a[n-i]);

    printf("%.5lf",find(l,r));
    return 0;    
}

例题:清华集训2015 灯泡

posted @ 2020-08-04 09:32  INFP  阅读(151)  评论(0编辑  收藏  举报