zoukankan      html  css  js  c++  java
  • 卡特兰数 应用

    卡特兰数真是一个神奇的数字,很多组合问题的数量都和它有关系,例如:

    • Cn= 长度为 2n的 Dyck words的数量。 Dyck words是由 n个 X和 n个 Y组成的字符串,并且从左往右数, Y的数量不超过 X,例如长度为 6的 Dyck words为:

    XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY

    • Cn= n对括号正确匹配组成的字符串数,例如 3对括号能够组成:

    ((())) ()(()) ()()() (())() (()())

    • Cn= n+1个数相乘,所有的括号方案数。例如, 4个数相乘的括号方案为:

     
    ((ab)c)d (a(bc))d (ab)(cd) a((bc)d) a(b(cd))

    • Cn= 拥有 n+1 个叶子节点的二叉树的数量。例如 4个叶子节点的所有二叉树形态:

    Catalan number binary tree example.png

    • Cn=n*n的方格地图中,从一个角到另外一个角,不跨越对角线的路径数,例如, 4×4方格地图中的路径有:

    Catalan number 4x4 grid example.svg

    • Cn= n+2条边的多边形,能被分割成三角形的方案数,例如 6边型的分割方案有:

    Catalan-Hexagons-example.svg

    • Cn= 圆桌周围有 2n个人,他们两两握手,但没有交叉的方案数。

    引用:http://blog.163.com/kevinlee_2010/blog/static/169820820201010894212352/

    求一个数的卡塔兰数

    使用递推式 H(n) = c(2n,n)/n+1;

    改写为A(2n,n)/ (n+1)!

    使用大数相乘相除计算

    #include <cstdio>
    #include <iostream>
    #include <cstring>

    using namespace std;

    #define N 250
    int a[N];

    void init(int n)
    {
        memset(a,0,sizeof(a));
        a[0] = 1;
        int i = 0;
        int j = 0;
        int k1 = 1;
        for(i = 2*n; k1 <= n; i--,k1++)
          {
              int t = 0;
              int mul = 0;
              for(j = 0; j <= N; j++)
                {
                   mul = a[j] *i + t;
                   a[j] = mul % 10;
                   t = mul / 10;
                }
          }

        for(i = 2; i <= n+1; i++)
            {
                int t1 = 0;
                int mul1 = 0;
                for(j = N; j >= 0;j--)
                    {
                        mul1 = mul1 *10 + a[j];
                        a[j] = mul1 / i;
                        mul1 %= i;
                    }
            }

      int k = N;
      while(k--)
       if(a[k])
         break;
        k += 1;
        while(k--)
          printf("%d",a[k]);
          printf("\n");
    }

    int main()
    {
        int n;
        while(scanf("%d",&n) != EOF)
         {
             if(n < 2)
               printf("%d\n",1);
            else
             init(n);
         }
        return 0;
    }

  • 相关阅读:
    详解 Android Activity 生命周期
    设计模式:装饰者模式
    析构函数virtual与非virtual区别 [转]
    详解 常量指针和指针常量
    [转]Python yield 使用浅析
    python 列表 总结
    [转]关于Python中的yield
    详解c++指针的指针和指针的引用
    转:Ogre源码剖析
    转:Ogre源码剖析1
  • 原文地址:https://www.cnblogs.com/yyroom/p/3035955.html
Copyright © 2011-2022 走看看