UVa 1331 - Minimax Triangulation(区间DP + 计算几何)
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4077
题意:
三角剖分是指用不相交的对角线把一个多边形分成若干个三角形。
输入一个简单m(2<m<50)边形,找一个最大三角形面积最小的三角剖分。输出最大三角形的面积。
分析:
和“最优三角剖分”一样,设d(i,j)为子多边形i,i+1,…,j-1,j(i<j)的最优解,
则状态转移方程为d(i,j)= min{S(i,j,k), d(i,k), d(k,j) | i<k<j},其中S(i,j,k)为三角形i-j-k的面积。
如果三角形i-j-k的内部有其他的点,则跳过。
代码:
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 6 const int UP = 50 + 5; 7 int n, x[UP], y[UP]; 8 double d[UP][UP]; // d[L][R]为子多边形L,L+1,…,R-1,R(L<R)的最优解 9 10 inline double area(int a, int b, int c){ // 知道三角形的三个点,用行列式求其面积 11 return 0.5*fabs(x[a]*(y[b]-y[c]) + x[b]*(y[c]-y[a]) + x[c]*(y[a]-y[b])); 12 } 13 14 bool judge(int a, int b, int c){ // 判断三角形abc的内部是否有其他的点 15 for(int i = 0; i < n; i++){ 16 if(i == a || i == b || i == c) continue; 17 double s = area(a,b,i) + area(a,c,i) + area(b,c,i) - area(a,b,c); 18 if(fabs(s) < 0.01) return false; 19 } 20 return true; 21 } 22 23 int main(){ 24 int T; 25 scanf("%d", &T); 26 while(T--){ 27 scanf("%d", &n); 28 for(int i = 0; i < n; i++) scanf("%d%d", &x[i], &y[i]); 29 30 for(int L = n - 2; L >= 0; L--){ 31 d[L][L+1] = 0; 32 for(int R = L + 2; R < n; R++){ 33 double& v = d[L][R]; v = 1e99; 34 for(int M = L + 1; M < R; M++) if(judge(L, M, R)) 35 v = min(v, max(area(L,M,R), max(d[L][M], d[M][R]))); 36 } 37 } 38 printf("%.1f\n", d[0][n-1]); 39 } 40 return 0; 41 }