十六種盒子放球問題的集合


大概是組合計數問題的基礎,因此稍微寫一下。

或者說,嘗試復習,發現自己都不會了,所以應該寫一下。

約定

這一類問題都可以在問題確定是,用兩個參數 \(n,r\) 來描述。其中 \(n\) 表示球數, \(r\) 表示盒數。

為了方便描述,以下用一串二進制碼表示問題的狀態。例如 0101

  1. 第一位表示球是否相同。 0 表示相同, 1 表示不同;
  2. 第二位表示盒是否相同。 0 表示相同, 1 表示不同;
  3. 第三位表示球可否不放。 0 表示不可, 1 表示可以;
  4. 第四位表示盒可否為空。 0 表示不可, 1 表示可以;

因此狀態 0101 就表示:球相同,盒不同,球不可不放,盒可以為空,此時的方案數。

另外,由於有些問題是筆者自己 yy 的,因此正確性存疑,該類問題用 * 標注。如果發現該部分有問題,請及時留言

11--

球不同、盒不同問題求解的基本途徑是乘法原理

1101

對於每一個球,它都有 \(r\) 種選擇。由於每個球不同,因此它們的選擇相互獨立,可以直接乘起來。

因此可以得到總方案數為 \(r^n\) ,求解的時間復雜度是 \(O(\log_2n)\)

1100

此時盒子不可以為空,但是直接乘法原理我們會得到盒子為空的方案。

注意乘法原理求到的是 " 至少有 0 個盒子為空 " 的方案數。因此不難想到用容斥原理計算。枚舉一下空盒子的數量,就可以方案數是:

\[\sum_{i=0}^r(-1)^i\binom{r}{i}(r-i)^n \]

求解的時間復雜度是 \(O(r\log_2n)\)

\(r\) 比較小的情況下,可以 \(O(r)\) 預處理自然數冪,然后求式子,時間復雜度是 \(O(r)\)

還可以發現,如果用指數型生成函數描述這個式子,我們可以在 \(O(r\log_2r)\) 的時間批量求出不同的 \(r\) 的解。

你會在之后再見到它的。

1110

這個時候,每個球就多了一個 " 不放 " 的選擇。因此每個球有 \(r+1\) 種選擇。總方案數是 \((r+1)^n\)

1111

繼續容斥:

\[\sum_{i=0}^r (-1)^i\binom{r}{i}(r+1-i)^n \]

01--

球相同、盒不同問題求解的基本原理是隔板法

0101

想象 \(n\) 個球排成一列。此時由於盒子是有區別的,因此我們可以將球分成 \(r\),然后第一組放進第一個盒子里,第二組放進第二盒......第 \(r\) 組放進第 \(r\) 盒。因此我們就考慮計算將 \(n\) 個球分成 \(r\) 組的方案數。

顯然這是隔板法的問題。 \(n\) 個球有 \(n-1\) 個縫,從 \(n-1\) 個縫中選出 \(r-1\) 個來插板的方案數是 \(\binom{n-1}{r-1}\)

0100

盒子可以為空,因此直接放板子不太對頭。經典的思想是:

我們給每個盒子先放一個 " 假球 " ,這樣總共有 \(n+r\) 個球,並且每個盒子至少有一個球(包括 " 假球 " )。現在再進行隔板法就沒有問題了,方案就是 \(\binom{n+r-1}{r-1}\)

0110*

由於球本身沒有區別,因此有球沒放就相當於球的數量變少了。於是就可以直接枚舉球的數量:

\[\begin{aligned} &\sum_{i=1}^n\binom{i-1}{r-1}\\ =&\sum_{i=1}^n\frac{(i-1)^{\underline{r-1}}}{(r-1)!}\\ =&\frac{1}{(r-1)!}\sum_{i=0}^{n-1}i^{\underline{r-1}}\\ =&\frac{1}{(r-1)!}\sum\nolimits_0^{n}x^{\underline{r-1}}\delta x\\ =&\frac{1}{(r-1)!}\frac{n^{\underline{r}}}{r}\\ =&\binom{n}{r} \end{aligned} \]

這個組合含義也比較顯然。我們同樣可以假想一個盒子,用來裝 " 沒放 " 的球。由於最后這個盒子可以為空,因此總共有 \(n\) 個縫, \(r\) 個板。

注意,盒子不能為空,因此這里不考慮不放球的情況。

0111*

同理易得:

\[\begin{aligned} &\sum_{i=0}^n \binom{i+r-1}{r-1}\\ =&\sum_{i=0}^n\frac{(i+r-1)^{\underline{r-1}}}{(r-1)!}\\ =&\frac{1}{(r-1)!}\sum_{i=0}^{n}(i+r-1)^{\underline{r-1}}\\ =&\frac{1}{(r-1)!}\sum\nolimits_{r-1}^{n+r}x^{\underline{r-1}}\delta x\\ =&\frac{1}{(r-1)!}\frac{(n+r)^{\underline{r}}-(r-1)^{\underline{r}}}{r}\\ =&\binom{n+r}{r} \end{aligned} \]

組合意義請自行思考。

注意,盒子可以為空,因此這里需要考慮球都不放的情況。

10--

球不同、盒相同問題求解的基本途徑是第二類斯特林數

1000

此時直接推導難度比較大,因此我們考慮使用 DP 。

\(f(i,j)\) :有 \(i\) 個球, \(j\) 個盒子,且球不同,盒相同時,球必須放,盒不能空的放球的方案數。

考慮轉移:

\[f(i,j)= \begin{cases} 1&i=0,j=0\\ 0&i<j\\ 0&i>0,j=0\\ f(i-1,j-1)+jf(i-1,j)&otherwise \end{cases} \]

最后一個轉移是在討論,在放最后一個球時,是否要新拿盒子。如果新拿一個,就是 \(f(i-1,j-1)\) 。如果不新拿,就從前 \(j\) 個盒子中挑一個放進去。

如果你有所了解,你就會發現,這是第二類斯特林數的遞歸式。這里我們記 \({n\brace r}=f(n,r)\)

因此這個問題的答案是 \(n\brace r\)

另一種推導方式 是,考慮容斥。我們先給盒子標號,然后枚舉空盒子的數量,最后把標號除掉:

\[{n\brace r}=\frac{1}{r!}\sum_{k=0}^r(-1)^k\binom{r}{k} (r-k)^n \]

可以發現,后面的容斥式實際就是 1100 的解。因此 1100 的解也可以表述為 \(r!{n\brace r}\)

另外,根據這個容斥式也可以使用 NTT 在 \(O(n\log_2n)\) 的時間內求出 \({n\brace 0},{n\brace 1},\dots,{n\brace k}\)

補充內容:

斯特林數原本用於描述階乘冪和冪之間的系數關系。第一類斯特林數 \(\begin{bmatrix}n\\k\end{bmatrix}\) 用於描述 \(x^{\underline{n}}\) 展開中 \(x^k\) 的系數,第二類 \(n\brace k\) 用於描述 \(x^n\) 展開中 \(x^{\underline{k}}\) 的系數。以此,冪和階乘冪就可以很方便地進行轉換。
因此可以得到關系式:

\[ x^{\underline{n}}=\sum_{k=0}^n\begin{bmatrix}n\\k\end{bmatrix} x^k\\ x^n=\sum_{k=0}^n{n\brace k} x^{\underline k} \]

當然,兩種數都有其對應的組合含義。

1001

不難想到,可以直接枚舉有球的盒子的數量:

\[\sum_{i=0}^r {n\brace i} \]

補充說明:

\(r=n\) 的時候,問題就變成了,對於大小為 \(n\) 的集合 \(S\) ,將它划分成任意多個非空子集的方案數是多少?
專門有一個數列 \(\{b_n\}\) 來描述它。這類數就叫 " 貝爾數 " 。
簡單推導(考慮第 \(n\) 個元素所在集合大小)可以得出貝爾數的轉移:

\[\begin{aligned} b_n&= \begin{cases} 1&n=0\\ \sum_{k=1}^{n} \binom{n-1}{k-1}b_{n-k}& otherwise \end{cases}\\ b_n&=\sum_{k=0}^n{n\brace k} \end{aligned} \]

可以定義 \(B(x)\) 為貝爾數的指數型生成函數,那么就有 \(B(x)=e^{e^x-1}\) 。具體推導可以參考 洛谷日報 等資料。

1010*

同樣可以枚舉球的數量:

\[\sum_{k=0}^n \binom{n}{k}{k\brace r} \]

你發現這個式子仍然可以使用 NTT 批量計算。甚至此情況的答案可以直接寫成生成函數形式。

1011*

同樣可以枚舉球和空盒子的數量:

\[\sum_{j=0}^n\binom{n}{j}\sum_{k=0}^r {j\brace k} \]

00--

球相同、盒相同問題求解的基本原理是動態規划

0001

不難發現,此時我們可以直接用每個盒子的球數組成的序列來描述一種方案。

那么我們只枚舉單調不減的序列就好了,也就是說,原問題的等價於求自然數序列的數量:

\[\begin{cases} \sum_{i=1}^r a_i=n\\ \forall 1<i\le r, a_{i-1}\le a_i \end{cases} \]

這里有一個很常見的轉化:枚舉單調不降序列,就相當於枚舉全是 1 的后綴的和
具體來說,我們可以定義

\[s_i=\{\underbrace{0\ 0\ \dots\ 0}_{i-1個0}\ \overbrace{1\ 1\ \dots\ 1}^{n-i+1個1}\} \]

那么一個單調不降的序列就必然可以拆分成多個 \(s\) 的對應位的和。比如 \(n=4\) 時, \(\{1\ 2\ 3\ 3\}=s_1+s_2+s_3\)

於是不難想到一個完全背包

\(g(i,j)\):在考慮完 \(s_1\sim s_j\) 后,所有后綴的和為 \(i\) 的方案數。

可以得到轉移為:

\[g(i,j)= \begin{cases} 1&i=0\\ 0&i>0,j=0\\ g(i-j,j)+g(i-1,j)&othewise \end{cases} \]

此時的答案就是 \(g(n,r)\)

0000

此時盒子不能為空,我們可以直接給每個盒子分配一個球。當 \(n<r\) 時,答案是 \(0\) 。當 \(n\ge r\) 時,答案就是 \(g(n-r,r)\)

0011*

球沒有區別,因此可以直接枚舉數量:

\[\sum_{k=0}^n g(k,r) \]

0010*

基本同上:

\[\sum_{k=r}^n g(k-r,r) \]

總結

盒子放球問題雖然模型簡單,但是你可以發現,在 16 種問題中,我們用了 4 種主要的思路:乘法原理、隔板法、斯特林數、動態規划,以及一些常見的技巧,比如容斥。每種主要思路下, 4 個子問題的方法不盡相同。不同主要思路下,處理子問題的限制的方法各自有些相似。

所以說,深入學習盒子放球,對於學習計數是比較有意義的。它的確可以幫助你熟悉一些基礎的計數方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM