卡特兰数数列 + 高精度代码
一、卡特兰数其实和斐波那契一样,就是一个数列,可以通过以下几种方式求出
给出部分卡特兰数:
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
二、这里给出c++按照第三种方式求解代码。
我们知道一个数的阶乘很容易爆掉long long,所以代码中就首先把分母和分子不乘起来,先约分最后才乘起来输出
输入一个数n,代码输出就是第n个卡特兰数
#include<iostream> #include<cstdio> using namespace std; #define maxn 550 int n; int a[maxn],b[maxn],ans[maxn*20]; int gcd(int a,int b) { if(!b) return a; else return gcd(b,a%b); } void mul(int x) { int k=0; for(int i=1;i<=ans[0];i++) { ans[i]*=x; ans[i]+=k; k=ans[i]/10; ans[i]%=10; } while(k) { ans[++ans[0]]=k%10; k/=10; } } int main() { scanf("%d",&n); for(int i=2;i<=n;i++)//经过化简的分子分母 { a[i-1]=i+n;//分子 b[i-1]=i;//分母 } for(int i=1;i<n;i++) { for(int j=1;j<n;j++) { if(b[j]==1) continue;//如果分母是1 则不用约 int d=gcd(a[i],b[j]); if(d!=1)//如果gcd不为1 则分子分母同时除gcd约分 { a[i]/=d; b[j]/=d; } if(a[i]==1) break;//如果分子已经约完就可以退出 } } //此时分母已经为1了 只需要把分子用高精乘起来即是ans ans[0]=ans[1]=1;//ans[0]为位数 for(int i=1;i<n;i++) { if(a[i]==1) continue; mul(a[i]); } for(int i=ans[0];i>=1;i--) printf("%d",ans[i]); }
三、这里给出java大数求排列组合代码
/* 求的结果以(C(m,n+m)-C(m+1,n+m))*n!*m!为例 */ import java.util.*; import java.math.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int cnt = 1; BigInteger []factor = new BigInteger[230]; factor[0] = BigInteger.ONE; for(int i = 1; i<=205; i++){ factor[i] = factor[i-1].multiply(BigInteger.valueOf(i)); } while(true){ int m = sc.nextInt(); int n = sc.nextInt(); if(m+n==0) break; System.out.println("Test #"+(cnt++)+":"); if(m<n){ System.out.println(0); continue; } else if(n==0){ System.out.println(factor[m]); continue; } BigInteger ans = factor[m+n].divide(factor[m]).divide(factor[n]); //System.out.println(ans); ans = ans.subtract(factor[m+n].divide(factor[m+1]).divide(factor[n-1])); //System.out.println(ans); //subtract是大数减大数函数 ans = ans.multiply(factor[m]).multiply(factor[n]); System.out.println(ans); } } }