CodeForces 437 E.The Child and Polygon(dp+计算几何)

202 篇文章 1 订阅
85 篇文章 0 订阅

Description
给出一个简单多边形,问其三角剖分方案
Input
第一行一整数n表示点数,之后顺时针或逆时针给出这n个点的坐标(3<=n<=200,|xi|,|yi|<=1e7)
Output
输出三角剖分方案数,结果模1e9+7
Sample Input
4
0 0
0 1
1 1
1 0
Sample Output
2
Solution
假设点逆时针排好并编号0~n-1,dp[i][j]表示i~j这些点构成的简单多边形的三角剖分数(i < j),每次从i+1~j-1这些点中找出一个k与i和j组成一个三角形,那么这个简单多边形就被分成i,i+1,..,k构成的简单多边形和k,k+1,…,j构成的简单多边形,进而有转移方程dp[i][j]=sum(dp[i][k]*dp[k][j]),其中i+1<=k<=j-1,且k的选择需使得由i,j,k三点构成的三角形与划分出来的两个简单多边形不会相交,判这个太麻烦,不如每次都选择向量ij右边的点k,这样就算相交出现不合法情况在之后的转移中迟早会找不到一个合法的k以供转移进而不会对答案有不合法的贡献
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 222
struct node
{
    ll x,y;
    node operator-(const node&b)const
    {
        node c;
        c.x=x-b.x,c.y=y-b.y;
        return c;
    }
    ll operator*(const node&b)const
    {
        return x*b.y-y*b.x;
    }
}p[maxn];
const ll mod=1e9+7ll;
ll dp[maxn][maxn];
int n;
ll dfs(int i,int j)
{
    if(dp[i][j]!=-1)return dp[i][j];
    if(i+1==j)return dp[i][j]=1;
    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;
    return dp[i][j]=ans;
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(dp,-1,sizeof(dp));
        for(int i=0;i<n;i++)scanf("%I64d%I64d",&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]);
        printf("%I64d\n",dfs(0,n-1));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值