码迷,mamicode.com
首页 > 其他好文 > 详细

【卡特兰数】【数论】

时间:2014-09-02 15:54:25      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:数论   卡特兰数   

前几个卡特兰数:规定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)



【卡特兰数】【数论】

标签:数论   卡特兰数   

原文地址:http://blog.csdn.net/u010468553/article/details/38986889

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!