首先,来说以个问题;若该多边形为凸多边形的话,
那么设 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; }