LintCode解题记录-Catalan Number
来源:互联网 发布:文明5 贸易网络 编辑:程序博客网 时间:2024/05/18 01:40
Catalan Number 卡特兰数
1.基本定义
组合数学中的知识,定义:令h(0) = h(1) =1, 则若h(n) = h(0)*h(n-1)+h(1)*h(n-2)+…+h(n-1)*h(0) (n >= 2),则称h(n)为卡特兰数。
例如:
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(4) = 14, h(5) = 42,…
另类递推式: 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(n, m)是从n中随机取m个的所有可能的取法(不考虑排列顺序)。
2.应用(重点)
1.矩阵链乘 括号化问题
令P = a1 x a2 x a3 x…x an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方式?(h(n)种,暂时没懂)
2.出栈次序
一个栈(无穷大)的入栈序列为1,2,3,…,n,请问一共有多少种出栈方式?
Step1: 设f(n)=序列个数为n时出栈序列种数。假设最后出栈的元素为k,显然k的取值是[1, n],且k取不同值时情况是相互独立的,因此可用加法原则将所有的k得到的出栈方式相加即是f(n)。
Step2: 由于k是最后出栈,那么在k入栈之前,比k小的元素均出栈(栈的先入后出原则),即1~k-1个元素出栈,有f(k-1)种方式。
Step3: 而之后比k大的数入栈,且都在k之前入栈,即k+1~n元素出栈,有f(n-k)种方式。为什么是f(n-k)呢,因为其实数的大小并不重要,重要的是数的个数,比如1,2,3,4,5和6,7,8,9,10得到的出栈方式显然是一样的。而k+1~n之间共有n-k个数,所以他们的出栈方式就有f(n-k)种了。
Step4: 根据乘法法则,得到f(k-1)*f(n-k)种,那么f(n) = Σf(k-1)*f(n-k) (k=1,…,n)
观察可得,这个递推式就是Catalan数的递推公式。
类似问题:买票找零
有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?
答: 将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈,那么上述问题就变成了n个数入栈然后有多少种出栈方式,答案就是Catalan Number.
3.凸多边形三角划分
在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。给定凸多边形的边数n,求不同划分的方案数f(n)。
思路就是以某一条边为基准,以这条边的两个顶点为起点P1和终点Pn,将该凸多边形的顶点依次标记为P1,P2,…,Pn,再在该凸边形中找任意一个不属于这两个顶点的Pk(2 <= k <= n-1)来构成一个三角形,用这个三角形把该凸边形划分成了两个凸边形,其中一个凸边形是由P1,P2..,Pk组成的凸k边形,另一个则是由Pk,Pk+1,..,Pn组成的凸n-k+1边形。
那么根据乘法原理,此时的划分总是就是f(k)*f(n-k+1),再根据不同k的加法原理,得到f(n) = Σf(k)*f(n-k+1),k的取值为[2, n-1]。结合Catalan数的递推公式,可以发现f(n) = h(n-2)。
4.LintCode Unique BST
给定n个节点,问能组成多少种不同的二叉搜索树。
考虑顶点为k时的情况,那么其左子树就是1~k-1所能组成的二叉搜索树,右子树就是k+1~n所能组成的二叉搜索树。根据乘法原理,顶点为k时所能得到的结果就是f(k-1)*f(n-k),再依据加法原理,得到f(n) = Σf(k-1)*f(n-k),k=1,2..,n
代码
int numTrees(int n) { // write your code here vector<int> dp(n+1, 0); dp[0] = dp[1] = 1; for (int i = 2; i <= n; i++) { for (int j = 0; j < i; j++) { dp[i] += dp[j] * dp[i-j-1]; } } return dp[n]; }
5.n对括号的正确匹配数
给定n对括号,求括号正确配对的字符串的个数。
考虑n对括号时任意一种配对方案,对于最后一个右括号,有与之唯一配对的左括号,于是该字符串可以理解为A(B),其中A和B也是正确配对的括号字符串。那么假设这个与之匹配的左括号是第k个左括号,显然第1~k-1个括号都在这个左括号之前得到了匹配,即上面所说的A,同理,k+1~n个左括号都在B中得到了匹配。依据乘法原理和加法原理,就可以得到f(n)=Σf(k-1)*f(n-k),k=1,2,..n,即Catlan Number。
- LintCode解题记录-Catalan Number
- LintCode 解题记录17.4.27
- LintCode解题记录17.4.28
- LintCode解题记录 17.5.3
- LintCode 解题记录 2017.6.3
- LintCode 解题记录 7.11 ~ 7.16
- LintCode 解题记录 Matrix专题
- LintCode解题记录17.9.9
- LintCode 解题记录17.10.21
- LintCode 解题记录 17.11.11
- Catalan number
- Catalan Number
- Catalan number
- LintCode 解题记录 17.5.15 (tag: 哈希表)
- LintCode 解题记录 17.5.22 (tag: Array)
- LintCode 解题记录 Array 17.6.5
- LintCode 解题记录 17.6.19~17.6.25
- LintCode 解题记录17.6.26 ~ 17.7.2
- CSS Mask 在WeGame新手引导的实践
- Maven配置环境变量
- web安全技术
- 魔法城市路径问题(腾讯2017校招笔试题)
- 将原始图片转换成TFRecord文件
- LintCode解题记录-Catalan Number
- 平滑滤波器的演化
- 兼容多种浏览器的,多行文本多余显示省略号(···)的方法
- 25. Reverse Nodes in k-Group 还未解决!!!
- 组件间通信 angualr4中间人模式
- 动画速度的控制
- poj3259 luogu2850 虫洞问题
- java深入学习六之正则表达式
- Python 中的random函数