扩大
缩小

三分

昨天晚修的时候在看必修五,看到线性规划,然后就在想直线相交的问题,然后不知道怎么做,就问hqm大佬,他说用三分,于是就去看了看三分,发现这是一个好东西啊!

我们可以先看下三分最最基本的用法

这里写图片描述

上图显然是一个单峰函数,如果我们要求它的峰值,显然我们找不到高效的算法,这时我们就要用三分了。

1、思路

三分法其实就是二分的升级,二分分成左右两段,而三分分成左中右三段,二分只有中点,而三分有左右两个三等分点(下文记左三等分点记为\(trip_l\),右三等分点记为\(trip_r\))。

如果\(f(trip_l)>f(trip_r)\)的话那么\(R=trip_r\)否则\(L=trip_l\)
这里写图片描述

这样我们的思路就极其清晰了

2、代码实现

这里我们就以Luogu P3382 【模板】三分法为例来看下三分法的具体实现。

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const double eps=1e-7;

int n;
double l,r,a[101];

double check(double x){
	double ret=a[0],tmp=x;
	for(int i=1;i<=n;i++){
		ret+=a[i]*tmp;
		tmp*=x;
	}
	return ret;
}

int main(){
	scanf("%d%lf%lf",&n,&l,&r);
	for(int i=n;i;i--){
		scanf("%lf",&a[i]);
	}
	while(r-l>eps){
		double tmp=(r-l)/3.0;
		double l1=check(l+tmp),r1=check(r-tmp);
		if(l1>r1)r=r-tmp;
		else {
			l=l+tmp;
		}
	}
	printf("%.5lf",l);
	return 0;
}
posted @ 2018-11-21 18:58  ezoiHY  阅读(689)  评论(0编辑  收藏  举报