第一类斯特林数:
我们考虑这样一个问题:有n个互不同的小球,拼成k个环,有几种拼法。数据量:n<=1000
这样的数据量,不难看出是一个n2n^{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)
本质:
也许读到这里会感到奇怪,这样的东西为什么会被发现,并且还单独列出来。
其实第一类斯特林数的本质就是排列数的系数。
Ank=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)
展开一下:
Ank=S(k,k)∗nk−S(k,k−1)∗nk−1+S(k,k−2)∗nk−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...
所以可以将它写成公式形式:
Ank=∑i=0k(−1)k−i∗S(k,i)∗niA_{n}^{k}=\sum_{i=0}^k(-1)^{k-i}*S(k,i)*n^iAnk=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=0m∗(−1)k∗Cmk∗(m−k)nS(i,j) = \sum_{k=0}^m*(-1)^k*C_m^k*(m-k)^nS(i,j)=k=0∑m∗(−1)k∗Cmk∗(m−k)n
即:枚举空的盒子数,然后容斥解决