SPOJ Make Triangle 卡特兰数,递推 1月25日

题目链接 : https://vjudge.net/problem/SPOJ-TRNGL

题意: 给出一个凸n边形,求用n-3条不相交的对角线将该n边形划分为三角形的方案数

解题思路: 其实就是卡特兰数,下面讲一下最基本的递推方法吧。因为凸多边形的任意一条边必定属于某一个三角形,所以我们以某一条边为基准,以这条边的两个顶点为起点P1和终点Pn(P即Point),将该凸多边形的顶点依序标记为P1、P2、……、Pn,再在该凸多边形中找任意一个不属于这两个点的顶点Pk(2<=k<=n-1),来构成一个三角形,用这个三角形把一个凸多边形划分成两个凸多边形,其中一个凸多边形,是由P1,P2,……,Pk构成的凸k边形(顶点数即是边数),另一个凸多边形,是由Pk,Pk+1,……,Pn构成的凸n-k+1边形。
此时,我们若把Pk视为确定一点,那么根据乘法原理,f(n)的问题就等价于——凸k多边形的划分方案数乘以凸n-k+1多边形的划分方案数,即选择Pk这个顶点的f(n)=f(k)×f(n-k+1)。而k可以选2到n-1,所以再根据加法原理,将k取不同值的划分方案相加,得到的总方案数为:f(n)=f(2)f(n-2+1)+f(3)f(n-3+1)+……+f(n-1)f(2)。看到此处,再看看卡特兰数的递推式,答案不言而喻,即为f(n)=h(n-2) (n=2,3,4,……)。
最后,令f(2)=1,f(3)=1。

代码如下:

#include <bits/stdc++.h>
using namespace std;
const long long mod = 100007;
long long dp[1010];

int main(){
    dp[2] = dp[3] = 1, dp[4] = 2;
    for(int i = 4; i <= 1000; i++){
        long long tmp = 0;
        for(int j = 2; j <= i - 1; j++){
            tmp = (tmp + dp[j] * dp[i - j + 1]) % mod;
        }
        dp[i] = tmp;
    }
    int T, n;
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        cout << dp[n] % mod << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值