题意:
按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值。
分析:
https://www.cnblogs.com/Konjakmoyu/p/4905563.html
对于对角线不在多边形内的点,其实不用考虑,只用判断三角形内是否有其他点即可。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=55;
double dp[maxn][maxn];
int x[maxn],y[maxn],n;
double area(int a,int b,int c){
double s=1.0/2*(x[a]*y[b]+x[b]*y[c]+x[c]*y[a]-x[a]*y[c]-x[b]*y[a]-x[c]*y[b]);
return fabs(s);
}
bool check(int a,int b,int c){
for(int i=1;i<=n;i++){
if(i==a||i==b||i==c){
continue;
}
double s=area(a,b,i)+area(a,c,i)+area(b,c,i)-area(a,b,c);
if(fabs(s)<=1e-6) return 0;
}
return 1;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
}
for(int i=n;i>=1;i--){
dp[i][i+1]=0.0;
for(int j=i+2;j<=n;j++){
dp[i][j]=inf;
for(int k=i+1;k<j;k++){
if(check(i,j,k))
dp[i][j]=min(dp[i][j],max(max(area(i,j,k),dp[i][k]),dp[k][j]));
}
}
}
printf("%.1f\n",dp[1][n]);
}
return 0;
}