题意:
三角剖分是指用不相交的对角线把一个多边形分成若干个三角形。
输入一个简单
m
m
m(
2
<
m
<
50
2\lt m\lt 50
2<m<50) 边形,找一个最大三角形面积最小的三角剖分。输出最大三角形的面积。
分析:
和“最优三角剖分”一样,设
d
(
i
,
j
)
d(i,j)
d(i,j) 为子多边形
i
i
i,
i
+
1
i+1
i+1,
⋯
\cdots
⋯,
j
−
1
j-1
j−1,
j
j
j(
i
<
j
i\lt j
i<j)的最优解,
则状态转移方程为
d
(
i
,
j
)
d(i,j)
d(i,j) =
min
(
S
(
i
,
j
,
k
)
,
d
(
i
,
k
)
,
d
(
k
,
j
)
)
∣
i
<
k
<
j
\min({S(i,j,k), d(i,k), d(k,j)) | i<k<j}
min(S(i,j,k),d(i,k),d(k,j))∣i<k<j,其中
S
(
i
,
j
,
k
)
S(i,j,k)
S(i,j,k) 为三角形
i
−
j
−
k
i-j-k
i−j−k 的面积。
如果三角形
i
−
j
−
k
i-j-k
i−j−k 的内部有其他的点,则跳过。
代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int UP = 50 + 5;
int n, x[UP], y[UP];
double d[UP][UP]; // d[L][R]为子多边形L,L+1,…,R-1,R(L<R)的最优解
inline double area(int a, int b, int c){ // 知道三角形的三个点,用行列式求其面积
return 0.5*fabs(x[a]*(y[b]-y[c]) + x[b]*(y[c]-y[a]) + x[c]*(y[a]-y[b]));
}
bool judge(int a, int b, int c){ // 判断三角形abc的内部是否有其他的点
for(int i = 0; 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) < 0.01) return false;
}
return true;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d%d", &x[i], &y[i]);
for(int L = n - 2; L >= 0; L--){
d[L][L+1] = 0;
for(int R = L + 2; R < n; R++){
double& v = d[L][R]; v = 1e99;
for(int M = L + 1; M < R; M++) if(judge(L, M, R))
v = min(v, max(area(L,M,R), max(d[L][M], d[M][R])));
}
}
printf("%.1f\n", d[0][n-1]);
}
return 0;
}