zoukankan      html  css  js  c++  java
  • 火车进出栈问题 【求卡特兰数】

    卡特兰数

    卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列。以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名,其前几项为(从第零项开始) : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...

    h(0)=1,h(1)=1catalan数满足递推式 [2]  

    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

    另类递推式 [3]  

    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. 数较小的情况下:

    n小的话,还可以用卡特兰数的递推公式 

    #include <bits/stdc++.h>

    using namespace std;

    const  int maxn=2e5+10;

    #define INF 0x3f3f3f;

    const int mod=998244353;

    typedef long long ll;

    int f[maxn];

    int main()

    {

        int n;

        cin>>n;

        f[0] = f[1] = 1;

        for(int i=2; i<=n; i++){

            for(int j=0; j<i; j++){

                f[i] += f[j] * f[i-j-1];

            }

        }

        cout<<f[n]<<endl;

        return 0;

    }

         

    1. 数较大的情况下:(java大数代码)

     

    用公式h(n)=C(2n,n)/(n+1) (n=0,1,2,...)

    将上下阶乘质因数分解,然后约掉相同的质因数之后再乘,最后再除 n+1

     

    import java.math.BigInteger;

    import java.util.Scanner;

    public class Main {

        static Scanner cin = new Scanner(System.in);

        static final int maxn = 200100;

        static int[] prime = new int[maxn];

        static boolean[] f = new boolean[maxn];

        static int k;

        static void init(){ //欧拉筛

            k = 0;

            for(int i=2; i<=maxn; i++){

                if(f[i] == false)

                    prime[k++] = i;

                for(int j=0; j<k && prime[j] * i < maxn; j++){

                    f[prime[j]*i] = true;

                    if(i % prime[j] == 0)  break;

                }

            }

        }

        static BigInteger qpow(int x,int b){

            BigInteger a = BigInteger.valueOf(x);

            BigInteger ret = BigInteger.valueOf(1);

            while(b != 0){

                if(b%2 == 1)  ret = ret.multiply(a);

                a = a.multiply(a);

                b >>= 1;

            }

            return ret;

        }

        public static void main(String args[]){

            int n;

            n = cin.nextInt();

            init();

            BigInteger ans = BigInteger.valueOf(1);

            int p,v;

            int cnt = 0;

            for(int i=0; i<k && prime[i] <= n*2; i++){ //2n/n!质因数相消

                cnt = 0;

                p = prime[i];

                v = n * 2;

                while(v > 0){

                    cnt += v/p;

                    v /= p;

                }

                v = n;

                while(v > 0){

                    cnt -= v/p * 2;

                    v /= p;

                }

                ans = ans.multiply(qpow(p,cnt));

            }

            BigInteger x = BigInteger.valueOf(n+1);

            ans = ans.divide(x);

            System.out.println(ans);

        }

    }

  • 相关阅读:
    文件上传
    gitee 提交项目
    SSM分页查询功能
    SSM 管理员删除功能
    SSM整合 管理员登录功能(密码加密功能)
    SSM整合项目 MD5加密工具类
    SSM Ajax发送复杂对象
    SSM环境中 Ajax 发送简单数组的三种方法
    ssm 增删改查
    ssm 登录功能
  • 原文地址:https://www.cnblogs.com/hao-tian/p/10434193.html
Copyright © 2011-2022 走看看