二分算法
三分板子
先看求导二分
\[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 灯泡