前言
感觉今天又颓了一个早上
来总结一下卡特兰数的不同形式和证明吧
应用
我觉得知道栈模型就差不多了。。
别的能转化就转化咯
形式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
)
我们考虑,枚举最后一个出栈的那个点的编号
i
i
那么在进来之前,
i−1
i
−
1
肯定已经出栈了,这个的方案是
f(i−1)
f
(
i
−
1
)
然后
i
i
后面的话,就是有的方案
然后乘起来就是答案了
这个的话,效率是
O(n2)
O
(
n
2
)
缺点就是时间很慢
但是优点是没有除法,在出题人毒瘤要你写高精度的时候可以减少码量
形式2
也就是组合数的形式
f(n)=Cn2n−Cn−12n
f
(
n
)
=
C
2
n
n
−
C
2
n
n
−
1
我们考虑,用全部减去不和法的
那么就是说现在你加入一个元素就是
(+1,+1)
(
+
1
,
+
1
)
,删除一个就是
(+1,−1)
(
+
1
,
−
1
)
你现在要从
(0,0)
(
0
,
0
)
走到
(2n,0)
(
2
n
,
0
)
的方案数
但是不能走到x轴一下
总的显然是
Cn2n
C
2
n
n
我们考虑如果经过了x轴,那么肯定会到达
y=−1
y
=
−
1
这一条直线
于是我们可以把第一次
y=−1
y
=
−
1
的后面,翻转过来
也就是加入一个元素就是
(+1,−1)
(
+
1
,
−
1
)
,删除一个就是
(+1,+1)
(
+
1
,
+
1
)
然后这样的话,走到
(2n,−2)
(
2
n
,
−
2
)
的方案数就是答案了
并且显然地,对于每一种走到
(2n,−2)
(
2
n
,
−
2
)
在你第一次到达
y=−1
y
=
−
1
的时候翻转都是一个合法的答案
然后就证完了
形式3
还是组合数的形式
f(n)=1n+1Cn2n
f
(
n
)
=
1
n
+
1
C
2
n
n
这个的话,证明也十分简单
我们考虑证明
Cn2n−Cn−12n=1n+1Cn2n
C
2
n
n
−
C
2
n
n
−
1
=
1
n
+
1
C
2
n
n
也就是要证明
Cn2n−1n+1Cn2n=Cn−12n
C
2
n
n
−
1
n
+
1
C
2
n
n
=
C
2
n
n
−
1
把式子展开可以得到
Cn2n−1n+1Cn2n=nn+1Cn2n=nn+1(2n)!n!n!=(2n)!(n+1)!(n−1)!
C
2
n
n
−
1
n
+
1
C
2
n
n
=
n
n
+
1
C
2
n
n
=
n
n
+
1
(
2
n
)
!
n
!
n
!
=
(
2
n
)
!
(
n
+
1
)
!
(
n
−
1
)
!
然后就和后面的式子一样了
形式3
f(n)=f(n−1)∗(4∗n−2)n+1
f
(
n
)
=
f
(
n
−
1
)
∗
(
4
∗
n
−
2
)
n
+
1
但是这个我并不会证明
但是你可以把这个式子拆开,可以得到一个比较好玩的形式
f(n)=Π(4∗i−2)(n+1)!
f
(
n
)
=
Π
(
4
∗
i
−
2
)
(
n
+
1
)
!
这样的话就是
O(n)
O
(
n
)
虽然我还没有想好这个东西怎么出题。。
但是这个形式还是挺好玩的吧。。也算是一个通项,雾)
CODE:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
int main()
{
LL n;
scanf("%lld",&n);
LL ans=1;
for (LL u=1;u<=n;u++) ans=ans*(4*u-2);
for (LL u=1;u<=n+1;u++) ans=ans/u;
printf("%lld\n",ans);
return 0;
}