火車進出棧問題



題目描述

一列火車n節車廂,依次編號為1,2,3,…,n。每節車廂有兩種運動方式,進棧與出棧,問n節車廂出棧的可能排列方式有多少種。

輸入

一個數,n(n<=60000)

輸出

一個數s表示n節車廂出棧的可能排列方式

樣例輸入

3

樣例輸出

5

分析

就是求個卡特蘭數,然而需要大整數。
這個題不能直接求,會TLE。需要先求出結果的每個質因數有多少次冪,然后用快速冪求,再把所有求冪得到的結果乘起來。
並不會算復雜度。

代碼

import java.math.*;
import java.util.*;
public class Main {
	static final int maxn=120050;
	static boolean[]isprime=new boolean[maxn];
	static int[] prime=new int[maxn];
	static int pz=0;
	static void getPrime() {
		for(int i = 2; i < maxn; ++i) isprime[i]=true;
		for(int i = 2; i < maxn; ++i) {
			if(isprime[i]) prime[pz++]=i;
			for(int j = 0; j < pz&&(long)i*prime[j]<maxn; ++j) {
				isprime[i*prime[j]]=false;
				if(i%prime[j]==0) break;
			}
		}
	}
	static Scanner cin=new Scanner(System.in);
	static int n=0;
	public static void main(String[] args) {
		n=cin.nextInt();
		getPrime();
		BigInteger ans=B(1);
		for(int i = 0; i < pz&&prime[i]<=2*n; ++i) {
			int cnt=0,p=prime[i];
			int t=n*2;
			while(t>0) {
				cnt+=t/p;
				t/=p;
			}
			t=n;
			while(t>0) {
				cnt-=t/p*2;
				t/=p;
			}
			ans=ans.multiply(pow(p,cnt));
		}
		System.out.println(ans.divide(B(n+1)));
	}
	static BigInteger pow(int x,int n) {
		BigInteger ans=B(1),base=B(x);
		while(n>0) {
			if(n%2==1) ans=ans.multiply(base);
			base=base.multiply(base);
			n>>=1;
		}
		return ans;
	}
	static BigInteger B(int x) {
		return BigInteger.valueOf(x);
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM