zoukankan      html  css  js  c++  java
  • nyoj164——卡特兰数(待填坑)

    题意:将1~2n个数按照顺时针排列好,用一条线将两个数字连接起来要求:线之间不能有交点,同一个点只允许被连一次。

    最后问给出一个n,有多少种方式满足条件。

    卡特兰数(列):

    令h(0)=1,h(1)=1,catalan数满足递推式:h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
    例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2               h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
    另类递推式:        h(n)=h(n-1)*(4*n-2)/(n+1);
    递推关系的解为: h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
    递推关系的另类解为:    h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...)

    一些方面的应用:

    1. 括号化:矩阵连乘:P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n-1)种)
    2.一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
    3.给定n个点求能组成的二叉树所有总数。
    4. 凸多边形三角划分(任意两顶点之间的连线必能相交),求有多少中分割的方法(类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数) 
    5. n层阶梯切割为n个矩形的切割方法总数

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 1000000;
    const int moder = 1000000;
    int a[105][100];
    void catalan()
    //求卡特兰数,a[i][j]存储的是第i个逆序(高位在后)的卡特兰数(从0开始),且未对高位0进行处理
    {
        int i, j, len, carry, temp;
        a[1][0] = 1;
        len = 1;
        for(i = 2; i <= 100; i++)
        {
            for(j = 0; j < len; j++) //乘法
                a[i][j] = a[i-1][j]*(4*(i-1)+2);
            carry = 0;
            for(j = 0; j < len; j++) //处理相乘结果
            {
                temp = a[i][j] + carry;
                a[i][j] = temp % 10;
                carry = temp / 10;
            }
            while(carry) //进位处理
            {
                a[i][len++] = carry % 10;
                carry /= 10;
            }
            carry = 0;
            for(j = len-1; j >= 0; j--) //除法
            {
                temp = carry*10 + a[i][j];
                a[i][j] = temp/(i+1);
                carry = temp%(i+1);
            }
        }
    }
    int main()
    {
        int n;
        catalan() ;
        while(scanf("%d",&n) ,n != -1)
        {
            int flag = 0 ;
            for(int i = 99;i >= 0;i--)//处理高位
            {
                if(a[n][i] != 0)
                    flag = 1;
                if(flag)
                    printf("%d",a[n][i]);
            }
            printf("
    ");
        }
        return 0;
    }

    ————不是很懂

  • 相关阅读:
    java web 初学
    学习2
    学习
    上课
    Java中字母大小写的转换
    心得体会
    servlet请求
    响应设置消息体
    servlet响应-头部信息的设置
    servlet的响应(一)
  • 原文地址:https://www.cnblogs.com/cunyusup/p/8587028.html
Copyright © 2011-2022 走看看