hdu1023 Train Problem II 卡特兰数,JAVA大数类
2016-03-19 11:52
615 查看
Train Problem II
[b]Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7578 Accepted Submission(s): 4081
[/b]
[align=left]Problem Description[/align]
As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the trains can get out of the railway.
[align=left]Input[/align]
The input contains several test cases. Each test cases consists of a number N(1<=N<=100). The input is terminated by the end of file.
[align=left]Output[/align]
For each test case, you should output how many ways that all the trains can get out of the railway.
[align=left]Sample Input[/align]
1 2 3 10
[align=left]Sample Output[/align]
1 2 5 16796 Hint The result will be very large, so you may not process it by 32-bit integers.
出栈次序
一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?[4-5]
常规分析
首先,我们设f(n)=序列个数为n的出栈序列种数。(我们假定,最后出栈的元素为k,显然,k取不同值时的情况是相互独立的,也就是求出每种k最后出栈的情况数后可用加法原则,由于k最后出栈,因此,在k入栈之前,比k小的值均出栈,此处情况有f(k-1)种,而之后比k大的值入栈,且都在k之前出栈,因此有f(n-k)种方式,由于比k小和比k大的值入栈出栈情况是相互独立的,此处可用乘法原则,f(n-k)*f(k-1)种,求和便是Catalan递归式。ps.author.陶百百)
首次出空之前第一个出栈的序数k将1~n的序列分成两个序列,其中一个是1~k-1,序列个数为k-1,另外一个是k+1~n,序列个数是n-k。
此时,我们若把k视为确定一个序数,那么根据乘法原理,f(n)的问题就等价于——序列个数为k-1的出栈序列种数乘以序列个数为n - k的出栈序列种数,即选择k这个序数的f(n)=f(k-1)×f(n-k)。而k可以选1到n,所以再根据加法原理,将k取不同值的序列种数相加,得到的总序列种数为:f(n)=f(0)f(n-1)+f(1)f(n-2)+……+f(n-1)f(0)。
看到此处,再看看卡特兰数的递推式,答案不言而喻,即为f(n)=h(n)= C(2n,n)/(n+1)= c(2n,n)-c(2n,n+1)(n=0,1,2,……)。
最后,令f(0)=1,f(1)=1。
令h(0)=1,h(1)=1,catalan数满足递推式[1] :
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
另类递推式[2] :
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,...)
本来想用C++记忆化递推,结果结果没超时,long long爆了。。。。
到几十的时候long long就已经爆了。。。
WA代码......
#include <cstdio> #include <iostream> #include <cstring> using namespace std; long long Cata[120], N; long long f(long long x) { if (Cata[x]) return Cata[x]; //记忆化搜索 long long sum = 0; for (long long i = 1; i <= x; i++) { sum += (f(i - 1) * f(x - i)); } return Cata[x] = sum; //记忆化搜索 } int main() { while (~scanf("%I64d", &N)) { memset(Cata, 0, sizeof(Cata)); Cata[0] = Cata[1] = 1; printf("%I64d\n", f(N)); } return 0; }
用java大数类做,用一个数组递推,慢就慢点吧,方便很多
import java.math.*; import java.util.Scanner; public class Main { public static void main(String[] args) { BigInteger[] c = new BigInteger[105]; c[0] = BigInteger.valueOf(1); c[1] = BigInteger.valueOf(1); for (int i = 2; i <= 100; i++) { c[i] = c[i - 1].multiply(BigInteger.valueOf(4 * i - 2)).divide(BigInteger.valueOf(i + 1)); } Scanner in = new Scanner(System.in); int n; while (in.hasNext()) { n = in.nextInt(); System.out.println(c ); } in.close(); } }
相关文章推荐
- java高级特性——动态代理
- 2016蓝桥杯假期任务之《泊松汾酒》
- 详解spring事务属性
- PMD-Java 代码检查工具对 error 和 warning 的配置
- Java IO--创建文件
- 深入理解Java虚拟机笔记---垃圾收集器
- java一周知识回顾
- myeclipse 改java文件后禁止自动重启- 热部署
- Java堆栈详解
- JAVA native method简介
- java -jar 执行 eclipse export 的 jar 包报错处理
- java 高级特性——注解
- java socket 编程
- spring分布式事务应用
- java 对象比较
- 【JAVA集合】LinkedHashMap及其源码分析
- spring mvc4:异常处理
- 借开发小工具做工作感悟
- 在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组
- Spring MVC 对于@ModelAttribute 、@SessionAttributes 的详细处理流程