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 }

 

posted @ 2018-03-21 13:40  Ctfes  阅读(184)  评论(0编辑  收藏  举报