HDU - 4372 Count the Buildings 組合數學 第一類斯特林數
阿新 • • 發佈:2020-08-20
第一類斯特林數
\[斯特林輪換式 S[n][k]表示將n個兩兩不同的元素,劃分為k個非空圓排列的方案數 \]
遞推式:
\[S[n][k] = S[n-1][k-1]+(n - 1)\cdot S[n-1][k] \]
邊界:
\[S[n][0]=[n=0] \]
HDU 4372
題意:
有n座高分別為\(1\sim n\)的城市在一條水平線上,從左能看到\(F\)座城市,從右能看到B座城市,問有幾種城市的排列方案。
題解:
首先最高的那座樓無論從左還是從右都會看到,因此最高的那座位置都是固定的。
從左看的\(F - 1\)座必然是高度遞增的,因此我們可以把這\(F-1\)座樓分組,每組的最左端也就是每組的最高的那座樓。組內剩下的$ k - 1$ 座進行全排列有\((k - 1)!\)
因此
\[ans = \tbinom{F-1+B-1}{F-1} \cdot S[n-1][F-1+B-1] \]
ll C[2005][2005]; ll S[2005][2005]; void get_C() { C[0][0] = 1; for (int i = 1; i <= 2000; i++) { C[i][0] = 1; for (int j = 1; j <= i; j++) C[i][j] = C[i - 1][j] + C[i - 1][j - 1], C[i][j] %= MOD; } } void get_S() { S[0][0] = 1; for (int i = 1; i <= 2000; i++) { for (int j = 1; j <= i; j++) S[i][j] = S[i - 1][j - 1] + (i - 1) * S[i - 1][j] % MOD, S[i][j] %= MOD; } } int main() { get_C(); get_S(); int T = readint(); while (T--) { ll n = readll(); ll f = readll(); ll b = readll(); if (f - 1 + b - 1 > n) { puts("0"); continue; } ll res = C[f - 1 + b - 1][f - 1] * S[n - 1][f - 1 + b - 1]; res %= MOD; Put(res); puts(""); } }