首先,来说以个问题;若该多边形为凸多边形的话,
那么设 d(i,j)代表以i节点为起点以j为最后一个点组成的多边形的最大面积最小的剖分;
有状态转移式子 d(i,j) = min( d[i][j] , max( max(d(i,k),d(k,j) ),s(i,k,j) )) (其中i<k<j ,s(i,k,j)为三点组成的三角形面积);
但对于不是凸多边形的话,上述式子在对k决策时,要额外满足一个条件i-->k,k-->j 两条线段必须都是多边形的对角线;
判断是否为对角线的话
首先该线段不和任一条边相交(不包括在端点相交),其次该线段在多边形内部;(判断第二个条件时,因为没啥好办法,就在线段上选了一个点(与任意顶点不同)来判断该
点是否在多边形内部;
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
const int inf = 1e9;
const int maxn = 55;
const double eps = 1e-10;
struct point{
double x,y;
point(double x=0,double y=0):x(x),y(y){}
}a[maxn];
double cross(point a,point b){
return a.x*b.y-a.y*b.x;
}
double dot(point a,point b){
return a.x*b.x+a.y*b.y;
}
point operator *(point a,double c){
return point(a.x*c+a.y*c);
}
point operator -(point a,point b){
return point(a.x-b.x,a.y-b.y);
}
int dcmp(double x){
if(fabs(x) < eps) return 0;
else return x<0 ? -1 : 1;
}
double trianglearea(point a,point b,point c){
return fabs(cross(b-a,c-a))/2.0;
}
bool SegmentProperIntersection(point a1,point a2,point b1,point b2){
double c1 = cross(a2-a1,b1-a1), c2 = cross(a2-a1,b2-a1),
c3 = cross(b2-b1,a1-b1), c4 = cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
/*not include point in each side;*/
bool isPointOnSegment(point p,point a1,point a2){
return dcmp(cross(a1-p,a2-p))==0 && dcmp(dot(a1-p,a2-p))<0;
}
int isPointinPolygon(point p){
int wn = 0;
for(int i=0;i<n;i++){
if(isPointOnSegment(p,a[i],a[(i+1)%n])) return -1;
int k = dcmp(cross(a[(i+1)%n]-a[i],p-a[i]));
int d1 = dcmp(a[i].y-p.y);
int d2 = dcmp(a[(i+1)%n].y-p.y);
if(k >0 && d1 <=0 && d2 >0) wn++;
if(k <0 && d2 <=0 && d1 >0) wn--;
}
if(wn !=0) return 1;
return 0;
}
bool Judge(int i,int j){
if(i+1==j) return true;
for(int k=0;k<n;k++){
if(SegmentProperIntersection(a[i],a[j],a[k],a[(k+1)%n]))
return false;
}
point c=a[i],d=a[j];
if(a[i].y > a[j].y){
swap(c.y,d.y);
swap(c.x,d.x);
}
point temp;
double fenmu = 50.0;
for(int k=1;k<=40;k++){
double dx = fabs((c.x-d.x))*k/fenmu;
double dy = fabs((c.y-d.y))*k/fenmu;
if(c.x < d.x){
temp.x = d.x - dx;
temp.y = d.y - dy;
}
else {
temp.x = d.x + dx;
temp.y = d.y - dy;
}
int ok = 1;
for(int g=0;g<n;g++){
if(dcmp(a[g].x-temp.x)==0 &&dcmp(a[g].y-temp.y)==0){
ok = 0; break;
}
}
if(ok) break;
}
if(isPointinPolygon(temp)==1) return true;
return false;
}
double d[maxn][maxn];
bool vis[maxn][maxn];
double dp(int i,int j){
if(vis[i][j]) return d[i][j];
vis[i][j] = true;
if(i+1==j){return d[i][j]=0;}
d[i][j] = inf;
for(int k=i+1;k<j;k++){
if(!Judge(i,k)||!Judge(k,j)) continue;
double s = trianglearea(a[i],a[k],a[j]);
d[i][j]=min(d[i][j],max(max(dp(i,k),dp(k,j)),s));
}
return d[i][j];
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf %lf",&a[i].x,&a[i].y);
}
memset(vis,false,sizeof(vis));
printf("%.1lf\n",dp(0,n-1));
}
return 0;
}