bzoj 4570 妖怪

bzoj 4570 妖怪

  • 正解应该是 (O(nlogn)) 的凸包,但被我的 (O(100n)) 的三分水过去了.
  • 记 $x=frac b a $ ,显然有 (strength_i=ATK_i+DFN_i+ATK_i cdot x+DFN_i cdot frac 1 x).
  • 每个(strength) 关于 (x) 是一个单峰函数,取最大值形成的函数也是一个单峰函数,三分 (x) 即可.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
	int x=0;
	bool pos=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar())
		if(ch=='-')
			pos=0;
	for(;isdigit(ch);ch=getchar())
		x=x*10+ch-'0';
	return pos?x:-x;
}
const double eps=1e-9;
const int T=100;
int dcmp(double x)
{
	return fabs(x)<eps?0:(x>0?1:-1);
}
double Max(double a,double b)
{
	return dcmp(a-b)>=0?a:b;
}
double Min(double a,double b)
{
	return dcmp(a-b)>=0?b:a;
}
const int MAXN=1e6+10;
int n;
double p[MAXN],q[MAXN];
double ans=1e18;
double calc(double x)
{
	double res=0;
	for(int i=1;i<=n;++i)
		{
			double str=p[i]+q[i]+p[i]*x+q[i]/x;
			res=Max(res,str);
		}
	return res;
}
double mx=0;
int main()
{
	n=read();
	for(int i=1;i<=n;++i)
		{
			scanf("%lf%lf",&p[i],&q[i]);
			mx=Max(mx,q[i]);
		}
	double L=eps*1000,R=1e8;
	for(int t=1;t<=T;++t)
		{
			double x1=L+(R-L)/3;
			double x2=R-(R-L)/3;
			double f1=calc(x1);
			double f2=calc(x2);
			if(dcmp(f1-f2)>=0)
				{
					ans=Min(ans,f2);
					L=x1;
				}
			else
				{
					ans=Min(ans,f1);
					R=x2;
				}
		}
	printf("%.4lf
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/jklover/p/10388848.html