【卡特兰数】【数论】

前几个卡特兰数:规定C0=1,而

C1=1,            C2=2,             C3=5,
             C4=14,            C5=42,

C6=132,       C7=429,         C8=1430,
      C9=4862,        C10=16796,

C11=58786,C12=208012,C13=742900,C14=2674440,C15=9694845。

求卡特兰数的公式有一下几个:

  1. h(n) = h(n-1)*(4*n-2)/(n+1)
  2. h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
  3. h(n)=C(2n,n)/(n+1)
    (n=0,1,2,...)
  4. h(n)=c(2n,n)-c(2n,n+1)(n=0,1,2,...)

下面给出一个卡特兰数的大数运算:能精确运算100以内的卡特兰数。

/* 大数解
对于大数来说,就应该使用下面的大数算法。
使用的公式为:h(n) = h(n-1)*(4*n-2)/(n+1);
*/
// 0ms
#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
#define MAX 100   //能计算的最大值10000^100,最大为400位
#define BASE 10000
void multiply(int a[],int Max,int b) //大数乘法,注意参数的传递
{
    int i,array=0;
    for (i = Max-1; i >= 0; i--)
    {
        array += b * a[i];
        a[i] = array % BASE;         // 数组每一位存放大数的四位数字
        array /= BASE;
    }
}
void divide(int a[], int Max, int b) //模拟大数除法
{
    int i, div = 0;
    for (i = 0; i < Max; i++)
    {
        div = div * BASE + a[i];
        a[i] = div / b;
        div %= b;
    }
}
int main()
{
    int a[101][MAX],i, n;
    memset(a[1],0,MAX*sizeof(int));
    for (i=2, a[1][MAX-1] = 1; i < 101; i++) // 高坐标存放大数低位
    {
        memcpy(a[i], a[i-1], MAX * sizeof(int));      //h[i] = h[i-1];
        multiply(a[i], MAX, 4 * i - 2);               //h[i] *= (4*i-2);
        divide(a[i], MAX, i + 1);                     //h[i] /= (i+1);
    }
    while (cin >> n)
    {
        for (i = 0; i < MAX && a[n][i] == 0; i++); //去掉数组前为0的数字。
        cout << a[n][i++];             //输出第一个非0数
        for (; i < MAX; i++)
        {
            printf("%04d",a[n][i]);       //输出后面的数,并每位都保持4位长度!(32767)
        }
        cout << endl;
    }
    return 0;
}

关于具体的运用别的博客上介绍的很清楚了。

下面只写出自己觉得有点意思的.........

12个人高低不同 站成两排,每一排的人必须是按照从低到高的顺序排,并且第一排对应的那个第二个人必须必第一排的人高。问一共有多少种方法。这个题目,我们可以这样来想:用0表示在第一排,用1表示在第二排。

比如000000111111表示的就是

1 2 3  4   5   6

7 8 9 10 11 12

000110001111 表示的就是

1 2 3  6   7   8

4 5 9 10 11 12

多少种排列方法就是满足所描述条件的排列有多少,很明显就是一个进栈出栈的问题了。

所以题目的答案就是卡特兰数(6)

时间: 2024-10-13 18:36:48

【卡特兰数】【数论】的相关文章

【数论】卡特兰数

Catanlan Number     卡特兰数,又称卡塔兰数(Catanlan Number),是一个非常多见.高深的数列.它能解决我们数论题目中一些计数问题.前几项为:1,2,5,14,42,132,429,1430,4862,16796,58786……          那么如何求Catanlan Number的第N项呢? 1. 2. 3. 4. 5. 着重需要介绍一下的是卡特兰数的功能 例一:二叉树的计数 n个非叶节点的满二叉树的形态数(对称后得到的二叉树除非自己本身对称,否则算是不同)

HDOJ/HDU 1133 Buy the Ticket(数论~卡特兰数~大数~)

Problem Description The "Harry Potter and the Goblet of Fire" will be on show in the next few days. As a crazy fan of Harry Potter, you will go to the cinema and have the first sight, won't you? Suppose the cinema only has one ticket-office and

卡特兰数(Catalan Number) 算法、数论 组合~

Catalan number,卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列.以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名. 卡特兰数的前几个数 前20项为(OEIS中的数列A000108):1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190

HOJ 13101 The Triangle Division of the Convex Polygon(数论求卡特兰数(模不为素数))

The Triangle Division of the Convex Polygon 题意:求 n 凸多边形可以有多少种方法分解成不相交的三角形,最后值模 m. 思路:卡特兰数的例子,只是模 m 让人头疼,因为 m 不一定是素数,所以不一定存在逆元. 解法:式子为f(n) =  ( C( 2*(n-2),  (n-2) ) / (n-1))   % m :令 p = n-2, 式子可化为:f(p) = ((2*p)! / ( p! * (p+1)! ) ) % m; 对 s!分解质因素,统计个

卡特兰数 3134 Circle

3134 Circle 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 在一个圆上,有2*K个不同的结点,我们以这些点为端点,连K条线段,使得每个结点都恰好用一次.在满足这些线段将圆分成最少部分的前提下,请计算有多少种连线的方法 输入描述 Input Description 仅一行,一个整数K(1<=K<=30) 输出描述 Output Description 两个用空格隔开的数,后者为最少将圆分成几块,前者为在此前提下连

NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推 ||卡特兰数(转化成01字符串))

Description 今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑.不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m.但是大家来的时间不同,随机次序来机房,带电脑的人直接准备比赛而没带电脑的人需要向带电脑并还没和别人公用的人求助(当然会答应).但是,如果不存在带电脑并还没和别人公用的人,那他就要等了,等是很让人头疼的,这就不和谐了,当然假如没有这样的情况发生比赛是很和谐的. Input 输入多组数据,每组数据只有一行m(

hdu 5177 (1e18范围的卡特兰数)

hdu 5177 (1e18范围的卡特兰数) 题意: 求第n个卡特兰数,模3814697265625 (5^18) 限制: 有20组数据,1 <= n <= 1e18 思路: 1. 卡特兰数的表达式: ans = 1/(n+1) * C(2*n,n) -> ans = 1/(n+1) * (2n)! / n! / n!    ---1式 2. 因为要模5^18,求逆元要求互质,所以先把"1式"中的因子5全部去掉 3. 然后看不含因子5的阶乘,f(n!) 4. 设g(x

hdu 4828 Grids(拓展欧几里得+卡特兰数)

题目链接:hdu 4828 Grids 题目大意:略. 解题思路:将上一行看成是入栈,下一行看成是出栈,那么执着的方案就是卡特兰数,用递推的方式求解. #include <cstdio> #include <cstring> typedef long long ll; const int N = 1000005; const ll MOD = 1e9+7; ll dp[N]; ll extendGcd(ll a, ll b, ll& x, ll& y) { if (

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)