HDU1023 Train Problem II(卡特兰数+大数)
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=1023
题意
此题是Train Problem I 的一个衍生,有一个站台(可以看做是栈,先进后出),给你一个数代表火车的个数,求这些火车进站再出站的方式有多少种。
思路
这是一道典型的卡特兰数的应用题(还有一些其他的应用,见这里)。
Catalan Number:卡特兰数是组合数学中一个常出现在各种计数问题中出现的数列。
卡特兰数前几项为 : C0=1,C1=1,C2=2,C3=5,C4=14,C5=42,C6=132,C7=429,C8=1430,C9=4862,C10=16796。
令h(0)=1,h(1)=1,Catalan数满足递推式: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
另类递推式: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,...)
另外注意,因为这题最大的数据到100,所以只能用大数,懒得写C++的,直接用java开搞。
AC代码
import java.io.*;
import java.math.BigInteger;
/**
* Created with IntelliJ IDEA.
*
* @author wanyu
* @Date: 2018-02-27
* @Time: 21:31
* To change this template use File | Settings | File Templates.
* @desc
*/
public class Main {
private static BigInteger Catalans[] = new BigInteger[110];//存储1到110的卡特兰数
public static void main(String[] args) throws IOException {
Catalans();
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int) in.nval;
out.println(Catalans[n]);
out.flush();
}
}
private static void Catalans() {//计算从1到110的卡特兰数
Catalans[0] = new BigInteger("1");//初始化
Catalans[1] = new BigInteger("1");//初始化
for (int i = 2; i < 110; i++) {
Catalans[i] = new BigInteger("0");
for (int j = 0; j < i; j++) {
BigInteger temp = Catalans[j].multiply(Catalans[i - j - 1]);
Catalans[i] = Catalans[i].add(temp);
}
}
}
}