题意
你需要找到 n n 个点,每个点离原点的距离分别为问 n n 个点形成的凸包的最大面积是多少(不要求所有 n n 个点都在凸包上)
题解
看到,想这题怕不是爆搜 ? ?
假设搜出了个点,分别是 a1…am a 1 … a m ,为了方便令 am+1=a1 a m + 1 = a 1
根据多边形面积的定义可以知道我们要最大化的就是 12∑mi=1rairai+1sinxi 1 2 ∑ i = 1 m r a i r a i + 1 sin x i ,其中 ∑mi=1xi=2π ∑ i = 1 m x i = 2 π
这是要求一个有条件最值,考虑用拉格朗日乘数法来试一试
设 f(x1,…,xn)=∑mi=1rairai+1sinxi,g(x1,…,xn)=∑mi=1xi=2π f ( x 1 , … , x n ) = ∑ i = 1 m r a i r a i + 1 sin x i , g ( x 1 , … , x n ) = ∑ i = 1 m x i = 2 π
在这题里面
这是 arccos arccos 的函数图像
然后考虑到 arccos arccos 是单调递减的所以可以二分求出当前的 λ λ
注意 λ∈[−min{rairai+1},min{rairai+1}] λ ∈ [ − m i n { r a i r a i + 1 } , m i n { r a i r a i + 1 } ]
#include<bits/stdc++.h>
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define go(u) for(register int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=10;
const double eps=1e-8,pi2=2*acos(-1);
typedef int arr[N];
int n,vis[N];double ans,p[N],q[N],r[N];
inline void chk(int m){
double L,R,T=1e6,mid,tp;p[m+1]=p[1];
fp(i,1,m)q[i]=p[i]*p[i+1],cmin(T,q[i]);L=-(R=T);
while(R-L>eps){
mid=(L+R)*0.5;tp=0;
fp(i,1,m)tp+=acos(mid/q[i]);
if(tp>=pi2)L=mid;
else R=mid;
}tp=0;if(T-L<eps)return;
fp(i,1,m)tp+=q[i]*sin(acos(L/q[i]));
cmax(ans,tp);
}
void dfs(int d){
if(d>3)chk(d-1);if(d==n+1)return;
fp(i,1,n-2)if(!vis[i])p[d]=r[i],vis[i]=1,dfs(d+1),vis[i]=0;
}
int main(){
// #ifndef ONLINE_JUDGE
file("yja");
// #endif
scanf("%d",&n);
fp(i,1,n)scanf("%lf",r+i);sort(r+1,r+n+1);
p[1]=r[n],p[2]=r[n-1];dfs(3);
printf("%.6lf",ans*0.5);
return 0;
}