大数的运算用 JAVA 实现
一、卡特兰数(catalan数)
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, ...
2、公式:
(1)、一般公式 ( 当 n > 35 时, long long )
令 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)
(2)、
h(n) = h(n-1)*(4*n-2) /(n+1)
(3)、
h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,…)
(4)、
h(n)=C(2n,n)/(n+1) (n=0,1,2,…)
3、如何判断卡特兰数 ?
记住前几项 1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 (下标从 0开始)
4、应用
(1)、出栈合法性 (买票找零):
一个栈(无穷大)的进栈序列为 1,2,3,...,n 问有多少个不同的出栈序列? h(n) 种
1、(分析)假定,最后出栈的元素为k。
显然,k 取不同值时的情况是相互独立的,也就是求出每种 k 最后出栈的情况数后可用加法原则。
因为 k 最后出栈,因此。在k入栈之前。比k小的值均出栈。此处情况有 f(k-1)种。
而之后比 k大的值 入栈。且都在k之前出栈。因此有 f(n-k) 种方式。
因为比k小和比k大的值 入栈出栈情况是相互独立的。此处可用乘法原则, f(n-k)*f(k-1)种,求和便是Catalan递归式
2、有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票
问有多少种方法使得只要有10元的人买票,售票处就有5元的钞票找零?
( 将持5元者到达视作将 5元入栈,持10元者到达视作 使栈中某5元出栈)
(2)、凸多边形三角划分:
凸 n+2 边形进行不同的三角形分割(只连接顶点对形成n个三角形)数为Catalan(N) h(n)种
(分析)求f(n)的问题等价于 —— 用k把凸多边形分成两部分,这时对于固定的k。
方案数w(k)=凸k多边形的划分方案数乘以凸n-k+1多边形的划分方案数
而k能够从2到n-1连续变化,即f(n)=w(2)+w(3)+...+w(n-1)
最后求和即得到卡特兰数的递推式。
当然,假设求凸多边形最优三角划分时,思路也是从k处断开。然后动态规划求解。
当n不大时,可考虑算好前n个Cartalan数直接返回。
(3)、矩阵连乘 (或者是 数连乘)
P = a1 * a2 * a3 * a4 *...... an
依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案 ? h(n) 种
(4)、由 n个 +1 和n个 -1 组成的排列中,满足前缀和 >=0 的排列有 h(n) 种。
(5)、给定 N 个节点,能构成 h(n) 种 形状不同的二叉树。
(6)、n个非叶节点的满二叉树的形态数为 h(n)种
(7)、对于一个 n*n 的正方形网格,每次只能 向右或者向上 移动一格,那么从左下角到右上角的不同种类有 h(n)种
(8)、对于在 n 位的2进制中,有m个0,其余为1的 catalan数为:C(n,m)-C(n,m-1)
(9)、将有 2n 个元素的集合中的元素 两两分为n个子集,若任意两个子集都不交叉,那么我们称此划分为一个不交叉划分。此 时不交叉的划分数是 h(n) 种
(10)、n 层的阶梯切割为 n 个矩形的切法数也是 h(n) 种
(11)、在一个2*n的格子中填入 1到2n 这些数值使得每个格子内的数值都比其右边和上边的所有数值都小的情况数也 是 h(n)种