火车进出栈问题(卡特兰数)
火车进出栈问题
时间限制: 1 Sec 内存限制: 128 MB提交: 42 解决: 10
[提交] [状态] [讨论版] [命题人:admin]
题目描述
一列火车n节车厢,依次编号为1,2,3,…,n。每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种。
输入
一个数,n(n<=60000)
输出
一个数s表示n节车厢出栈的可能排列方式
样例输入
3
样例输出
5
思路:
易得答案为 第n项卡特兰数, 可以通过卡特兰数的通项公式 C(2n,n)/(n+1) 求出。
由于数据比较大,我们使用 Java 中的大数,(担心超时,就分解质因数)。
代码如下:
import java.math.BigInteger; import java.util.Scanner; public class Main{ static final int maxn=120010; static boolean[] nt=new boolean[maxn]; static int []prime=new int[maxn]; static int pn=0; static int n; static BigInteger ans=setB(1); static BigInteger setB(int x){ return BigInteger.valueOf(x); } static void init() { nt[0] = true; for (int i = 2; i < maxn; i++) { if (!nt[i]) prime[pn++] = i; for (int j = 0; j < pn && i * prime[j] < maxn; j++) { nt[i * prime[j]] = true; if (i % prime[j] == 0) break; } } } static void solve(){ for (int i=0; i<pn && prime[i]<=2*n; i++){ int cnt=0,pri=prime[i],tmp=n<<1; while(tmp>0){ cnt+=tmp/pri; tmp/=pri; } tmp=n; while(tmp>0){ cnt-=tmp/pri*2; tmp/=pri; } ans=ans.multiply(setB(pri).pow(cnt)); } } static Scanner cin=new Scanner(System.in); public static void main(String argc[]){ init(); n=cin.nextInt(); solve(); System.out.println(ans.divide(setB(n+1))); } }