POJ 2084 Game of Connections(卡特兰数)

  卡特兰数源于组合数学,ACM中比较具体的使用例子有,1括号匹配的种数。2在栈中的自然数出栈的种数。3求多边形内三角形的个数。4,n个数围城圆圈,找不相交线段的个数。5给定n个数,求组成二叉树的种数……

  此题就是第4个样例,是裸卡特兰数,但是这里牵扯的大数,可以使用java的大数类解决,但是我这里使用高精度乘法和除法模拟的(主要是java不会)。

  此处的递推式为H【1】 = 1;H【n】 = H【n-1】*(4*n-2)/(n+1){n>=2};代码如下:

  需要注意输出的形式,我这里的进制是1000,还可以更大,根据需求吧。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define jz 10000
int a[110][110];
void chengfa(int k,int num){
    int jw = 0;
    for(int i = 100;i >= 0;i--){
        jw += a[k-1][i] * num;
        a[k][i] = jw % jz;
        jw /= jz;
    }
}
void chufa(int k,int num){
    int div = 0;
    for(int i = 0;i <= 100;i++){
        div = div*jz + a[k][i];
        a[k][i] = div / num;
        div %= num;
    }
}
void init(){
    memset(a,0,sizeof(a));
    a[1][100] = 1;
    int num;
    for(int i = 2;i <= 100;i++){
        num = (4*i-2);
        chengfa(i,num);
        num = i+1;
        chufa(i,num);
    }
}
int main()
{
    init();
    int n;
    while(~scanf("%d",&n)){
        if(n==-1) break;
        int pos = -1;
        for(int i = 0;i <= 100;i++){
            if(a[n][i]){
                pos = i;
                break;
            }
        }
        printf("%d",a[n][pos]);
        for(int i = pos+1;i <= 100;i++){
            printf("%04d",a[n][i]);
        }
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jifahu/p/5571503.html