The Child and Polygon
题意:题目给出一个多边形,问有几种方案将其分割成多个三角形,且满足以下五点:
- each vertex of each triangle is one of the polygon vertex;
- 三角形的每个点都是多边形的顶点;
- each side of the polygon must be the side of exactly one triangle;
- 多边形的每条边都必须是一个三角形的边;
- the area of intersection of every two triangles equals to zero, and the sum of all areas of triangles equals to the area of the polygon;
- 三角形面积和就是多边形的面积,即三角形之间不能重叠,不能有缝隙;
- each triangle must be completely inside the polygon;
- 所构成的三角形都必须完全在多边形内部;
- each side of each triangle must contain exactly two vertices of the polygon.
- 三角形的每条边都必须连接多边形的两个顶点;
思路:这里其实是用到了分治的思想;先把多边形分成两个多边形,结果就是两个多边形分别进行三角形剖分方案的乘积;
题目给出的点可能是顺时针,也可能是逆时针,这里我把它们全部转换成顺时针顺序;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
struct node{
ll x, y;
node operator - (const node& a)const{
node c;
c.x=x-a.x;
c.y=y-a.y;
return c;
}
ll operator * (const node& a)const{
return x*a.y-y*a.x;
}
}p[220];
ll dp[220][220];
ll dfs(int i, int j){
if(i+1==j) return 1;
if(dp[i][j]!=-1) return dp[i][j];
ll ans=0;
for(int k=i+1; k<j; k++){
if((p[k]-p[i])*(p[j]-p[i])>0) ans=(ans+dfs(i, k)*dfs(k, j)%mod)%mod;
}
dp[i][j]=ans;
return dp[i][j];
}
int main(){
int n;
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%lld%lld", &p[i].x, &p[i].y);
}
ll s=0;
for(int i=0; i<n; i++){
s+=p[i]*p[(i+1)%n];
}
if(s<0){
for(int i=0, j=n-1; i<j; i++, j--){
swap(p[i], p[j]);
}
}
memset(dp, -1, sizeof(dp));
printf("%lld\n", dfs(0, n-1));
return 0;
}