题目
思考
分析: 选取i作为根节点 则
左子树分支为1:i-1
右子树分支为i+1:n 亦即 1:n-i
故而问题可转化为: n个节点的树=(所有i) i-1节点 * n-i节点
具体
示例中 f(3)= f(0)*f(2) +f(1)*f(1) +f(2)*f(0)
易知:
0个节点 f(0)=0
1个节点 f(1)=1
2个节点 f(2)=2
f(3)= 0*2 + 1*1 + 2*0 but ---> 0:含义无子树 故 此时应另 f(0)=1
通用性: n个节点---> 确定第i个 剩余n-1个节点 左右两分支子问题
故可以通过 f(0) f(1) ===> f(2)
f(0) f(1) f(2) ===> f(3)
f(0) f(1) f(2) f(3) ===> f(4)
....
====> f(n)
算法实现
# -*- encoding: utf-8 -*-
def focution(n):
f = [0] * (n + 1)
f[0], f[1] = 1, 1
for i in range(2, n + 1):
for j in range(1, i + 1):
f[i] += f[j - 1] * f[i - j]
return f[n]
if __name__ == "__main__":
param = input("节点数:")
print("种类:", focution(int(param)))
pass
类似问题: 跳台阶f(n)=f(n-1)+f(n-2)…
[1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796] 卡特兰数
卡特兰数
出入栈序列: C2nn / (n+1)
卡特兰数,又称卡塔兰数,是组合数学中一种常出现于各种计数问题中的数列。以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名。1730年左右被蒙古族数学家明安图 (1692-1763)使用于对三角函数幂级数的推导而首次发现,1774年被发表在《割圜密率捷法》。 百度百科
明安图数,又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现于各种计数问题中的数列。以中国蒙古族数学家明安图 (1692-1763)和比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名,其前几项为(从第零项开始) : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796,… 百度百科
经典问题
-
进出栈序列
我们将进栈表示为 +1,出栈表示为 -1,则 1 3 2 的出栈序列可以表示为:+1 -1 +1 +1 -1 -1。
根据栈本身的特点,每次出栈的时候,必定之前有元素入栈, 即对于每个 -1 前面都有一个 +1 相对应。因此,出栈序列的 所有前缀和 必然大于等于 0,并且 +1 的数量 等于 -1 的数量。接下来让我们观察一下 n = 3 的一种出栈序列:+1 -1 -1 +1 -1 +1。序列前三项和小于 0,显然这是个
非法的序列
。如果将
第一个 前缀和小于 0 的前缀,即前三项元素都进行取反
,就会得到:-1 +1 +1 +1 -1 +1。此时有 3 + 1 个+1
以及 3 - 1 个-1
。因为这个小于 0 的前缀和必然是 -1,且 -1 比 +1 多一个,取反后,-1 比 +1 少一个,则 +1 变为 n + 1 个,且 -1 变为 n - 1 个。
进一步推广,对于 n 元素的每种非法出栈序列,都会对应一个含有 n + 1 个 +1 以及 n - 1个 -1 的序列
。如何证明这两种序列是一一对应的?
假设非法序列为 A,对应的序列为 B。每个 A 只有一个"第一个前缀和小于 0 的前缀",所以每个 A 只能产生一个 B。而每个 B 想要还原到 A,就需要找到"第一个前缀和大于 0 的前缀",显然 B 也只能产生一个 A。
每个 B 都有 n + 1 个
+1
以及 n - 1 个-1
,因此 B 的数量为 C2nn+1,相当于在长度为 2n 的序列中找到n + 1个位置存放 +1。相应的,非法序列的数量也就等于 C2nn+1 。出栈序列的总数量共有 C2nn ,因此,合法的出栈序列的数量为 C2nn - C2nn+1 。
-
括号序列
n 对括号,则有多少种 “括号匹配” 的括号序列
左括号看成 +1,右括号看成 -1,那么就和上题的进出栈一样 -
满二叉树
n + 1 个叶子节点能够构成多少种形状不同的(国际)满二叉树
(国际)满二叉树定义:如果一棵二叉树的结点要么是叶子结点,要么它有两个子结点,这样的树就是满二叉树。
使用深度优先搜索这个满二叉树,向左扩展时标记为 +1,向右扩展时标记为 -1。由于每个非叶子节点都有两个左右子节点,所有它必然会先向左扩展,再向右扩展。总体下来,左右扩展将会形成匹配,即变成进出栈的题型。
n + 1个叶子结点会有 2n 次扩展. -
凸变形三角划分
在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)。比如当n=6时,f(6)=14。
因为凸多边形的任意一条边必定属于某一个三角形,所以我们以某一条边为基准,以这条边的两个顶点为起点P1和终点Pn(P即Point),将该凸多边形的顶点依序标记为P1、P2、……、Pn,再在该凸多边形中找任意一个不属于这两个点的顶点Pk(2<=k<=n-1),来构成一个三角形,用这个三角形把一个凸多边形划分成两个凸多边形,其中一个凸多边形,是由P1,P2,……,Pk构成的凸k边形(顶点数即是边数),另一个凸多边形,是由Pk,Pk+1,……,Pn构成的凸n-k+1边形。ok … 二叉搜索树问题 -
电影购票
电影票一张 50 coin,且售票厅没有 coin。m 个人各自持有 50 coin,n 个人各自持有 100 coin。则有多少种排队方式,可以让每个人都买到电影票。
电影购票
持有 50 coin 的人每次购票时不需要找零,并且可以帮助后面持有 100 coin 的人找零;而对于持有 100 coin 的人每次购票时需要找零,但 100 coin 对后面的找零没有任何作用。
因此,相当于每个持有 100 coin 的人都需要和一个持有 50 coin 的人进行匹配。我们将持有 50 coin 的标记为 +1,持有 100 coin 的标记为 -1,此时又回到了进出栈问题。
不同的是,m 并一定等于 n
,且 排队序列是一种排列,需要考虑先后顺序
,例如各自持有 50 coin 的甲和乙的前后关系会造成两种不同的排队序列。所以,将会有
第二项为什么是Cm+nm+1,其实很简单,我们每次把第一个前缀小于0 的前缀取反后,会造成 +1 多了一个而 -1 少了一个。这里 +1 有 m 个,-1 有 n 个,取反后 +1 变成m + 1个,-1 变成n - 1个,总和不变。