模拟赛考了扩展卡特兰,然鹅我连卡特兰数是什么都不知道,打的爆搜。
本来以为是难度较高的知识,结果一搜好多普及组的题…
卡特兰数
如果你能把一道求方案数的题的模型转化成,有两个选择,设成1,-1,每个位置的选择表示成1,-1,当前缀和s>0时,选择合法,s<0时不合法,求方案数。或者有当前方案数能用 i - 1的方案数和n-i的方案数求出。
那么这道题可以直接用卡特兰数解
经典的题就是进栈出栈,括号匹配,给定直线求不超过直线到终点的方案数,等。
我们还是用一道题来了解卡特兰数
洛谷上就有经典的题P1044栈
我们先将模型转换
首先我们可以知道,进出站的数
a
i
=
i
a_i = i
ai=i也就是数列是严格递增的,
我们设k为当前最后一个出栈的数, 设f[n]表示n个数全部出栈的方案数,那么f[0] = 1, f[1] = 1;
那么当k出栈后,k出栈前的数能够分为两种:
一种是大于k的数,
一种是小于k的数,
大于k的数一定比k后进栈,小于k的数一定比k先进栈,于是k就把整个进出栈的数字分为两部分。
那么对于前面的一部分:
即小于k的部分,我们可以用f[k-1]表示出来,对于大于k 的部分,我们可以用f[n-k]表示出来。
那么k的方案数就是f[k-1] * f[n-k]
对于这道题,每一个数都可能是最后一个输出的
所以答案就是
∑
i
=
1
n
f
[
i
−
1
]
∗
f
[
n
−
i
]
\sum_{i=1}^nf[i-1]*f[n-i]
∑i=1nf[i−1]∗f[n−i]
那么这个就是卡特兰数,
即一个数列存在关系f[0] = 1, f[1] = 1, 并且满足递推式
f
[
n
]
=
f
[
0
]
∗
f
[
n
−
1
]
+
f
[
1
]
∗
f
[
n
−
2
]
.
.
.
f
[
n
−
1
]
∗
f
[
0
]
f[n] = f[0] * f[n-1] + f[1] * f[n-2] ... f[n-1] * f[0]
f[n]=f[0]∗f[n−1]+f[1]∗f[n−2]...f[n−1]∗f[0]
当然数学家们看见这么复杂的递推式就想着把式子化简,
于是就有了递推式
f
[
n
]
=
f
[
n
−
1
]
∗
(
4
n
−
2
)
n
+
1
f[n] = \frac{f[n-1] * (4n -2)}{n+1}
f[n]=n+1f[n−1]∗(4n−2)
∑
i
=
0
n
(
n
2
n
)
−
(
n
−
1
2
n
)
或
者
(
n
2
n
)
n
+
1
\sum_{i=0}^n\binom{n}{2n} - \binom{n-1}{2n}或者\frac{\binom{n}{2n}}{n+1}
∑i=0n(2nn)−(2nn−1)或者n+1(2nn)
可以根据公式转换模型,判断是否能用卡特兰数解