Hdu 2067 小兔的棋盘 (卡特兰数)

题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2067、
题目大意:
一个大小为 nn 的棋盘,从左下角走到右下角,每次只能向上或者向右走,不能穿越对角线,一共有多少种走法
分析:
先考虑右下三角的情况,最后总数乘2即可
http://blog.sina.com.cn/s/blog_6aefe4250101asv5.html
http://www.cnblogs.com/wuyuegb2312/p/3016878.html#suggestion
http://blog.sina.com.cn/s/blog_4298002e0100eko0.html
几篇关于卡特兰数详细解释的博客
我的理解,卡特兰数主要用于解决,一个变量被另一个变量限制的问题,比如:
括号匹配,有一个右括号必然之前要有一个左括号,即在放下一个右括号之前,序列中的左括号数必须大于右括号数
再或者公园找零问题
2n个人排队买票,其中n个人持50元,n个人持100元。每张票50元,且一人只买一张票。初始时售票处没有零钱找零。请问这2n个人一共有多少种排队顺序,不至于使售票处找不开钱?
若想找的开钱,那在收100元之前,已收50元的数目必须大于100元的数目
再比如当前的问题
若要不穿越对角线,则向上走的步数必须时刻小于等于向右走的步数
第一步一定向右走,假设第k步向上走,一共要走 2n 步,同时 2 k1 k+1 2n 也满足这个性质
卡特兰数主要有几个式子可求

h(n)=Cn2nn+1

h(n)=Cn2nCn12n

h(n)=h(0)h(n1)+h(1)h(n2)++h(n1)h(0)

这题不能使用第一二个公式,因为 n35 过于大, C3570 的值会爆longlong 所以使用第三个公式打表即可

#include
#include
#include
#include
#include
#include 
#define mod 1000000007
using namespace std;
typedef long long ll;
ll ctl[109]={1,1};
void init()
{
    for (int i = 1 ; i <= 36 ; i ++)
    {
        ctl[i]=0;
        for (int j = 0 ; j < i ; j ++)
            ctl[i]+=ctl[j]*ctl[i-j-1];
    }

}

int main()
{
    init();
    int n,ca=1;
    while (~scanf("%d",&n))
    {
        if (n==-1)
            break;
        printf("%d %d %I64d\n",ca++,n,2*ctl[n]);
    }
}

你可能感兴趣的:(数论,数论,卡特兰数)