第一类斯特林数:
我们考虑这样一个问题:有n个互不同的小球,拼成k个环,有几种拼法。数据量:n<=1000
这样的数据量,不难看出是一个
n
2
n^{2}
n2的DP或者说递推。
我们假设S(n,k)表示前n个小球,拼成k个环的方案数。
这样看似要知道每一个环中有几个小球,但是其实我们可以直接添加小球。
我们可以假设把小球加到某一个已经拼好的小球后面,那么这样就能枚举到每种情况。并且它是一个环,所以不用枚举当前小球在某一个环的头部的情况。
还有一种它自成一环的情况,累计一下就好了。
那么可以写出递推式:
S
(
i
,
j
)
=
(
i
−
1
)
∗
S
(
i
−
1
,
j
)
+
S
(
i
−
1
,
j
−
1
)
S(i,j)=(i-1)*S(i-1,j)+S(i-1,j-1)
S(i,j)=(i−1)∗S(i−1,j)+S(i−1,j−1)
本质:
也许读到这里会感到奇怪,这样的东西为什么会被发现,并且还单独列出来。
其实第一类斯特林数的本质就是排列数的系数。
A
n
k
=
n
∗
(
n
−
1
)
∗
(
n
−
2
)
∗
.
.
.
∗
(
n
−
k
+
1
)
A_{n}^{k}=n*(n-1)*(n-2)*...*(n-k+1)
Ank=n∗(n−1)∗(n−2)∗...∗(n−k+1)
展开一下:
A
n
k
=
S
(
k
,
k
)
∗
n
k
−
S
(
k
,
k
−
1
)
∗
n
k
−
1
+
S
(
k
,
k
−
2
)
∗
n
k
−
2
.
.
.
A_{n}^{k}=S(k,k)*n^k-S(k,k-1)*n^{k-1}+S(k,k-2)*n^{k-2}...
Ank=S(k,k)∗nk−S(k,k−1)∗nk−1+S(k,k−2)∗nk−2...
所以可以将它写成公式形式:
A
n
k
=
∑
i
=
0
k
(
−
1
)
k
−
i
∗
S
(
k
,
i
)
∗
n
i
A_{n}^{k}=\sum_{i=0}^k(-1)^{k-i}*S(k,i)*n^i
Ank=i=0∑k(−1)k−i∗S(k,i)∗ni
第二类斯特林数:
同样,考虑一个问题:有n个互不同的数,放入成k个非空集合,有几种放法。数据量:n<=1000
有了上一个递推的基础,这显然也是一个递推。
S(i,j)表示前i个数,组成j个集合的方案数。
有了上一个递推的基础,不难写出递推式:
S
(
i
,
j
)
=
j
∗
S
(
i
−
1
,
j
)
+
S
(
i
−
1
,
j
−
1
)
S(i,j)=j*S(i-1,j)+S(i-1,j-1)
S(i,j)=j∗S(i−1,j)+S(i−1,j−1)
upd:
第二类斯特林数的容斥形式:
S
(
i
,
j
)
=
∑
k
=
0
m
∗
(
−
1
)
k
∗
C
m
k
∗
(
m
−
k
)
n
S(i,j) = \sum_{k=0}^m*(-1)^k*C_m^k*(m-k)^n
S(i,j)=k=0∑m∗(−1)k∗Cmk∗(m−k)n
即:枚举空的盒子数,然后容斥解决