标签:技术分享 2-2 ret 操作 ons -- 简单 表示 names
第一次知道三分还是在HEOI2017的时候听THU大佬讲题,当时一脸茫然
后来也没碰到过这种题,一直都是用二分(贼啦好使)
不过今天去刷题库里的 [Ahoi2014]宅男计划 的时候,发现需要用三分法,于是就过来填了这个坑QvQ
其实对于二分查找需要满足的单调性,三分是用来查找一个凸性函数
简单来讲呢,就是函数中存在一个点x是最大(小)值,对于x的左边,满足单调上升(下降),右边满足单调下降(上升),然后我们进行一些“精彩操作”使得不断的逼近这个x点,最后求得答案

我们对于[L,R],先找出mid,紧接着再找出[mid,R]的midmid,然后比较两者谁更优,然后舍去不优的
我们不用担心选出来的mid 和 midmid 是在x的同侧还是异侧,因为如果异侧满足(吗)对称性,同侧的话满足单调性,最后都会选出最优解,舍弃不优的。
于是乎,我们就向x逼近了。
我没上来就打 [Ahoi2014]宅男计划 ,而是先去luogu找了个板子
如题,给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减。试求出x的值。
第一行一次包含一个正整数N和两个实数l、r,含义如题目描述所示。
第二行包含N+1个实数,从高到低依次表示该N次函数各项的系数。
输出为一行,包含一个实数,即为x的值。四舍五入保留5位小数。
3 -0.9981 0.5 1 -3 -3 1
-0.41421
时空限制:50ms,128M
数据规模:
对于100%的数据:7<=N<=13
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define pos2(i,a,b) for(int i=(a);i>=(b);i--)
#define N 210000
#define LL long long
const double eps=1e-10;
int n;
double l,r;
double a[N];
double check(double x){
double ans=a[n+1];
pos2(i,n,1){
double temp=a[n-i+1];
pos(j,1,i){
temp*=x;
}
ans+=temp;
}
return ans;
}
int main(){
scanf("%d%lf%lf",&n,&l,&r);
pos(i,1,n+1){
scanf("%lf",&a[i]);
}
while(l+eps<r){
double mid=(l+r)/2;
double mmid=(mid+r)/2;
if(check(mid)>check(mmid)) r=mmid;
else l=mid;
}
printf("%0.5lf",r);
return 0;
}
标签:技术分享 2-2 ret 操作 ons -- 简单 表示 names
原文地址:http://www.cnblogs.com/Hallmeow/p/7611816.html