1. 程式人生 > >第一類斯特林數、第二類斯特林數、貝爾數總結+模板

第一類斯特林數、第二類斯特林數、貝爾數總結+模板

第一類斯特林數  解決問題:給n個元素,求出k個環排列的方法數  Stirling[n][k] 1 1      1 2      3       1 6      11      6       1 24     50      35      10     1 120    274     225     85     15     1 720    1764    1624    735    175    21    1 5040   13068   13132   6769   1960   322   28   1 40320  109584  118124  67284  22449  4536  546  36  1 362880 1026576 1172700 723680 269325 63273 9450 870 45 1

const int maxn = 21;
ll Stirling[maxn][maxn], fac[maxn] = {1};
void init() {
	for(ll i = 1; i < maxn; i++)
		fac[i] = fac[i - 1] * i;
	Stirling[0][0] = 0;
	Stirling[1][1] = 1;
	for(ll i = 2; i < maxn; i++) {
		for(ll j = 1; j <= i; j++) {
			Stirling[i][j] = Stirling[i - 1][j - 1] + (i - 1) * Stirling[i - 1][j];
		}
	}
}

第二類斯特林數  將n個不同元素拆分成m個集合的方案數 Stirling[n][m] 1 1 1 1 3   1 1 7   6    1 1 15  25   10    1 1 31  90   65    15    1 1 63  301  350   140   21    1 1 127 966  1701  1050  266   28   1 1 255 3025 7770  6951  2646  462  36  1 1 511 9330 34105 42525 22827 5880 750 45 1

const int maxn = 21;
ll Stirling[maxn][maxn];
void init() {
	Stirling[0][0] = 0;
	Stirling[1][1] = 1;
	for(ll i = 2; i < maxn; i++) {
		for(ll j = 1; j <= i; j++) {
			Stirling[i][j] = Stirling[i - 1][j - 1] + j * Stirling[i - 1][j];
		}
	}
}

貝爾數 n個數可以劃分成多少個集合 每個貝爾數是第二類斯特林數的和  Bell[n]

const int maxn = 21;
ll Bell[maxn];
void init() {
	ll T[maxn];
	Bell[0] = 1;
    Bell[1] = 1;
    T[0] = 1;
    for(int i = 2; i < maxn; i++) {
        T[i - 1] = Bell[i - 1];
        for(int j = i - 2; j >= 0; j--)
            T[j] = T[j] + T[j + 1];
        Bell[i] = T[0];
    }
}