題意是乙個人有姓和名,都是有n個字元組成的。要求乙個人的姓何名不能出現相同的字元。現在有m個字元,問你一共可以有多少不同的人。
首先我們先學習下斯特林數。
第一類stirling數s(p,k)
第一類stirling數的含義:將p個物體排成k個非空迴圈排列的種類數。
s(p,k)=s(p-1,k-1)+s(p-1,k)*(p-1)。1<=k<=p-1 s(p,0)=0,s(p,p)=1
遞推關係的說明:
考慮第p個物品,p可以單獨構成乙個非空迴圈排列,這樣前p-1種物品構成k-1個非空迴圈排列,方法數為s(p-1,k-1);
也可以前p-1種物品構成k個非空迴圈排列,而第p個物品插入第i個物品的左邊,這有(p-1)*s(p-1,k)種方法。
第二類stirling數s(p,k)
含義:將p個物體劃分成k個不可分辨的集合的方法數。
k!s(p,k)是將p個物體劃分成k個可分別(有編號)的集合的方法數。
s(p,k)=s(p-1,k-1)+s(p-1,k)*k; s(p,p)=1;s(p,0)=0;
那麼對於這道題,我們可以列舉姓和名的字元數分別為i,j;
那麼答案為c(m,i)*f(n,i)*c(m-i,j)*f(n,j)。f(n,i)表示在這n個位置中放i個字元的方法數。可以知道f(n,i)=i!*s(n,i)
也可以根據容斥原理 f(
n,x)
=xn−
(x1)
(x−1
)n+(
x2)(
x−2)
n−(x
3)(x
−3)n
+...
**如下:
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll s[2010][2010],c[2010][2010],pow[2010];
void init()
}c[0][0]=1;c[1][0]=1;c[1][1]=1;
for(int i=2;i<=2000;i++)}}
void powd()
}int main()
}printf("%i64d\n",ans);}}
斯特林數 斯特林反演
第一類stirling數 s n,m 也可記為 beginn m end 第一類stirling分為無符號第一類stirling數 s u n,m 和帶符號第一類stirling數 s s n,m 他們分別表現為其公升階函式和降階函式的各項係數,形式如下 x x cdot x 1 cdot x 2 ...
斯特林數(Stirling)
第一類斯特林數表示的是將n個不同元素分成k個不同的環的方案數。兩個環不相同當且僅當這兩個環不能通過旋轉得到。記作s n,k 遞推關係的說明 1.考慮第n個物品,n可以單獨構成乙個非空迴圈排列,這樣前n 1種物品構成k 1個非空迴圈排列,方法數為s n 1,k 1 2.也可以前n 1種物品構成k個非空...
有關斯特林數
這種情況即只需要考慮每個人左邊是誰就ok啦。考慮第n個人怎麼插入,他既可以直接自己成乙個環,也可以插到之前的人中間。s n,k s n 1,k 1 s n 1,k n 1 因為這個人有n 1個地方可以塞進去 s n,k 表示n個人站成k個圓的方案數 與上面的區別是,上面需要考慮每個圓裡面的元素是怎麼...