【模板】三分法
来源:https://www.luogu.com.cn/record/40832798
题目描述
如题,给出一个N次函数,保证在范围 [l, r] 内存在一点 x,使得 [l, x]上单调增,[x, r]上单调减。试求出 x值。
输入格式
第一行一次包含一个正整数 NN 和两个实数 l, r含义如题目描述所示。
第二行包含 N + 1个实数,从高到低依次表示该 N次函数各项的系数。
输出格式
输出为一行,包含一个实数,即为 x的值。四舍五入保留 5位小数。
输入
3 -0.9981 0.5
1 -3 -3 1
输出
-0.41421
说明/提示
对 于 100 % 的 数 据 , 7 ≤ N ≤ 13 。 对于 100\%的数据,7 \le N \le 13。 对于100%的数据,7≤N≤13。
思路:三分的模板题呀~就不具体的写题解啦,直接看代码吧,写的挺详细的
二分适用于单调函数,三分适用于单峰函数。
#include<bits/stdc++.h>
using namespace std;
int n ;//n次函数
double l,r,midl,midr,k;//l,r为定义域范围,midl,midr为三分两端范围
const double eps=1e-6;//保留五位小数,所以精度范围设置为六位,(试了五位只能过三个点)
double a[15];
double f(double x){
double sum=0;
for(int i=0;i<=n;i++)//函数用循环表示
sum=x*sum+a[i];
return sum;
}
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;//将范围分为三份
midl=l+k;//左端三分点
midr=r-k;//右端三分点
if(f(midl)>f(midr))//说明midl更接近极点,所以将右边的范围向左移
r=midr;
else
l=midl;
}
printf("%.5lf\n",l);
return 0;
}
欢迎大家友好评论呀~,有啥错误dd我呀。。