首页 > 其他分享 >三分法

三分法

时间:2024-03-02 23:45:51浏览次数:16  
标签:三分法 pi return point int double include

三分(洛谷P3382)


题目大意

给出一个N次函数,保证在\([l,r]\)内存在一点x使得\([l,x]\)上单调递增,\([x,r]\)上单调递减,求出x的值。

解题思路

三分区间,对左端点与右端点的函数值进行比较缩小区间,直到所求x达到精度要求。

未知的代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	double L,R;
	cin>>n>>L>>R;
	vector<double>a(n+1);
	for(int i=0;i<=n;i++)cin>>a[i];
	auto solve=[&](double k){
		double ans=0;
		for(int i=0;i<=n;i++)ans=ans*k+a[i];
		return ans;
	};
	while(R-L>=1e-6){
		double k=(R-L)/3;
		if(solve(L+k)>solve(R-k))R-=k;
		else L+=k;
	}
	cout<<fixed<<setprecision(5)<<L<<endl;
	return 0;
}

三分·三分求极值 (hihocoder 1142)


题目大意

求一个抛物线与某一点的最短距离。

解题思路

三分区间,通过比较求得的左端点距离与右端点距离缩小区间直到达到精度要求。

未知的代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	double a,b,c,x,y,l=-2e2+5,r=2e2+5;
	cin>>a>>b>>c>>x>>y;
	auto solve=[&](double k){
		double func=a*k*k+b*k+c;
		double res=hypot(x-k,y-func);
		return res;
	};
	while(r-l>1e-8){
		double k=(r-l)/3;
		if(solve(l+k)<solve(r-k))r-=k;
		else l+=k;
	}
	cout<<fixed<<setprecision(3)<<(solve(l)+solve(r))/2<<endl;
	return 0;
}

Line belt(hdu 3400)


题目大意

二位坐标上四个点A,B,C,D,AB段速度为P,CD段速度为Q,其余位置速度为R,求A到D的最短时间。

解题思路

分析知,点A将从AB段的某点离开,进入CD段的某点到D。(都包含端点)那么使用三分嵌套分别求出AB离开点和CD进入点即可得到答案。

未知的代码
#include<bits/stdc++.h>
using namespace std;
struct point{
    double x,y;
    point (){}
    point (double x,double y):x(x),y(y) {}
    point operator * (int a){
        return point (x*a,y*a);
    }
    point operator / (int a){
        return point(x/a,y/a);
    }
    point operator + (point a){
        return point (x+a.x,y+a.y);
    }
    point operator - (point a){
        return point (x-a.x,y-a.y);
    }
}a,b,c,d;
int P,Q,R;
const double eps=1e-9;
 
double dis(point x,point y){
	return hypot(x.x-y.x,x.y-y.y);
//    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
 
double solve(point l,point r){
    return dis(a,l)/P+dis(l,r)/R+dis(r,d)/Q;
}
 
double find(point l,point r,point k)
{
    double ans=1e8;
    do
    {
        point ll=((l*2)+r)/3;
        point rr=(l+(r*2))/3;
        double ans1=solve(k,ll);
        double ans2=solve(k,rr);
        ans=min(ans1,ans2);
        if(ans1>ans2)l=ll;
        else r=rr;
    }while(dis(l,r)>eps);
    return ans;
}
double find(point l,point r)
{
    double ans=1e8;
    do
    {
        point ll=((l*2)+r)/3;
        point rr=(l+(r*2))/3;
        double ans1=find(c,d,ll);
        double ans2=find(c,d,rr);
        ans=min(ans1,ans2);
        if(ans1>ans2)l=ll;
        else r=rr;
    }while(dis(l,r)>eps);
    return ans;
}
 
int main() {
    int t;
    cin>>t;
    while (t--) {
    	cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y>>P>>Q>>R;
    	cout<<fixed<<setprecision(2)<<find(a,b)<<endl;
    }
    return 0;
}

期末考试(洛谷P3745)


题目大意

期末考试后,参与考试的n个同学的最晚期望出全部成绩的时间为\(t_i\),m门课程的出分时间为\(b_i\),每个同学每多等一天出分就会产生C的不愉快度,问通过以下两种操作后最小的不愉快度之和是多少?

  • 让学科X晚一天发布,学科Y早一天发布,产生A不愉悦度。
  • 让学科Z早一天发布,产生B不愉悦度。

解题思路

未知的代码


三分 | 函数(洛谷P1883)


题目大意

给定n个形如\(ax^2+bx+c\)的二次函数,设\(F(x)\)为这n个函数中最大的那个,求\(F(x)\)在\([0,1000]\)中的最小值。

解题思路

三分函数值,在判断函数里,计算出所有函数在该点下的值并返回其最大值,最后得到某点满足所有函数中最大,在其他最大情况中值最小。

未知的代码
//有个数据点未过
#include<bits/stdc++.h>
using namespace std;
int main(){
	int t,n;
	vector<array<int,3>>param;
	cin>>t;
	auto calc=[&](double x){
		double ans=0;
		for(int i=1;i<=n;i++){
			ans=max(ans,param[i][0]*x*x+param[i][1]*x+param[i][2]);
		}
		return ans;
	};
	while(t--){
		cin>>n;
		param=vector<array<int,3>>(n+1);
		for(int i=1;i<=n;i++)cin>>param[i][0]>>param[i][1]>>param[i][2];
		double l=0,r=1e3;
		for(int i=1;i<=100;i++){
			double m1=l+(r-l)/3,m2=r-(r-l)/3;
			if(calc(m1)>calc(m2))l=m1;
			else r=m2;
		}
		cout<<fixed<<setprecision(4)<<calc(l)<<endl;
	}
	return 0;
}

Texas Trip(poj 3301)


题目大意

二维平面上有n个小孔,找出覆盖全部小点的最小正方形面积。

解题思路

在标准二维坐标系中确定x轴向最远两点,y轴向最远两点,对其在\([0,\frac{\pi}{2}]\)区间内旋转,确定满足覆盖全部孔的正方形的边长,由此产生的正方形的面积将构成一个凹函数,三分符合要求的最小边长求面积即可。

未知的代码
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
const double pi=acos(-1);
const int inf=0x3f3f3f3f;
const int N=50;
int n;
struct node{
	double x,y;
}p[N];
double calc(double a){
	double maxx=-inf,maxy=-inf,minx=inf,miny=inf;
	for(int i=1;i<=n;i++){
		maxx=max(maxx,p[i].x*cos(a)-p[i].y*sin(a));
		maxy=max(maxy,p[i].x*sin(a)+p[i].y*cos(a));
		minx=min(minx,p[i].x*cos(a)-p[i].y*sin(a));
		miny=min(miny,p[i].x*sin(a)+p[i].y*cos(a));
	}
	return max(maxx-minx,maxy-miny);
}
int main(){
	int t;
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++)cin>>p[i].x>>p[i].y;
		double l=0,r=pi;
		for(int i=1;i<=100;i++){
			double m1=l+(r-l)/3,m2=r-(r-l)/3;
			if(calc(m1)>calc(m2))l=m1;
			else r=m2;
		}
		cout<<fixed<<setprecision(2)<<pow(calc(l),2)<<endl;
	}
	return 0;
}

UmBasketella (poj 3737)


题目大意

给定锥体表面积,求最大体积。

解题思路

锥体表面积:\(S=\pi r+\pi rl,V=\frac{1}{3}Sh\),体积取决于底面半径\(r\)和圆锥高\(h\),根据\(l^2-r^2=h^2\)三分半径,求得最值.

未知的代码
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;    
const double pi = acos(-1);
double s, v,h,l;
double calc(double r){
    l = (s - pi*r*r)/(pi*r);
    h = sqrt(l*l - r*r);
    v = (h*pi*r*r)/3.0;
    return v;
}
int main(){
    while(cin>>s){
    	double l=0,r=sqrt(s/pi/2);
    	while(r-l>1e-5){
    		double m1=l+(r-l)/3,m2=r-(r-l)/3;
    		if(calc(m1)>calc(m2))r=m2;
    		else l=m1;
		}
		cout<<fixed<<setprecision(2)<<v<<endl<<h<<endl<<r<<endl;
    }
    return 0;
}


Communication System(poj 1018)


题目大意

有n个设备,每个设备有mi个厂家生成,包含带宽B和价格P两个指标,B是全部所选设备的最小贷款值,P是所选所有设备价格总和,要给每个设备选出一个厂家,使B/P尽可能大。

解题思路

本体用动态规划解最优,也可枚举贪心求解。

未知的代码
#include<iostream>
#include<iomanip>
#include<cstring>
using namespace std;
const int N=105;
int b[N];
int p[N];
int dp[N][N*N];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        memset(dp,-1,sizeof(dp));
        cin>>n;
        int maxb=0;
        for(int i=1;i<=n;i++){
            cin>>m;
            for(int j=1;j<=m;j++){
                cin>>b[j]>>p[j];
                maxb=max(maxb,b[j]);
            }
            if(i==1){
                for(int j=1;j<=m;j++)
                    dp[i][b[j]]=p[j];
                continue;
            }
            for(int k=0;k<=maxb;k++){
                if(dp[i-1][k]==-1)continue;
                for(int j=1;j<=m;j++){
                    int mb=min(k,b[j]);
                    if(dp[i][mb]==-1)dp[i][mb]=dp[i-1][k]+p[j];
                    else dp[i][mb]=min(dp[i][mb],dp[i-1][k]+p[j]);
                }
            }
        }
        double ans=0;
        for(int i=0;i<=maxb;i++)
            ans=max(ans,(1.0*i)/dp[n][i]);
        cout<<fixed<<setprecision(3)<<ans<<endl;
    }
    return 0;
}

标签:三分法,pi,return,point,int,double,include
From: https://www.cnblogs.com/eternal-world/p/17935606.html

相关文章

  • 三分法
    三分法是二分法的变种,他最基本的用途是求单峰函数的极值点。三分适用的情况:有唯一的最大值,满足最大值左侧严格单调递增,右侧严格单调递减(或左减右增)。强调严格单调,这样在确定最值是才能判断最值的位置,否则三分法不能缩小左右边界。三分整数模板整数的三分可能具有不确定性,可以......
  • 【学习笔记】【自学】【模板】三分法
    题目描述:给定一个$n$次函数$f(x)$形如$a_1x^n+a_{2}x^{n-1}+......+a_{n-1}x^2+a_nx+a_{n+1}$,求$f(x)_{\max}$,且$x\in[l,r]$,设使得$f(x)_{\max}$的$x$为$x_{\max}$。对于一个区间$[l,r]$而言,若确定使得$f(x)$为最大值的$x$定在$[l,r]$中,则可以使用三分法求......
  • wzOI 2023.8.24 模拟赛(附树的直径和三分法)
    2023-08-2815:53:53$$A$$典型错误一知半解看样例型:如果该队某个数组的值比最大值大就算入答案。上第一次厕所前我的思路:开局\(30\)分钟。显然,我并不需要有一个数值最大才能赢,我只需要其中一个数值比其中一个数值比其中一个数值最大的那个要大的队要大即有可能获胜......
  • 4.12 三分法学习笔记
    三分的思路和二分有一点像。正好这两天数学在学函数的单调性,所以感觉还不错。但是三分法出题似乎有一定的局限性,所以应用并不广泛,但是还是需要学习一下。P3382【模板】三分法 一个洛谷三分的板子。三分求单峰函数极值。三分适用的情况:有唯一的最大值,满足最大值左侧严格单调递......
  • 和菜鸟一起学算法之三分法求极值问题
    7年,唉,可是他错了,女孩根本不爱他,不过期间他的执着和付出,很让我感动,也许自己不太像他那样,才会让自己有现在的处境吧。也许吧。小感慨下。不过现在也挺好的,上上班,写写文章,然后......
  • 二分法&三分法模板
    二分法求函数零点longdoublel=INT_MIN,r=INT_MAX,mid,eps=1e-6;while(r-l>eps){ mid=(l+r)/2; if(f(mid)<0)l=mid; elser=mid;}cout<<l<<endl;三分法......
  • P5931 [清华集训2015]灯泡——三分法
    一道不错的题,只是重构数据后精度太奇怪了,必须打表才能过题目分析根据题意我们可以抽象出一个直角梯形,并设人到墙壁的距离为\(x\),设影子在墙上的高度为\(y\)如果没有在......