放球問題在組合數學中是乙個經典問題,在acm比賽中也經常會出現類似的題目,這裡做乙個歸納。
我們假定現在有n個球,要放到m個盒子中,根據情況的不同主要可以分為一下8類(這裡確保n>=m)
編號n個球是否有區別
m個盒子是否有區別
是否允許空盒1否
否是2否
否否3否
是否4否
是是5是
否否6是
否是7是
是否8是
是是我們對這些情況逐一分析。
假設dp[i][j]為球相同,盒相同,允許空盒,且有i個球,j個盒子的結果。那麼我們可以分成兩種情況,一種是放完有空盒的情況,那麼我減去乙個盒子不影響結果。還有一種是每乙個盒子至少有乙個球,那我們可以把每個盒子裡拿去乙個球,那就變成了(i-j)個球,j個盒子的結果了,即dp[i-j][j],兩部分相加即可構成狀態轉移方程。
dp[i][j]=dp[i][j-1]+dp[i-j][j]; (i>=j)dp[i][j]=dp[i][j-1]; (i
預處理後可以o(1)查詢,預處理**見下
void init()
}
ps:如果(n
由於要求沒有空盒,我們先在每個盒子裡放乙個球即可,剩下(n-m)個球可以隨意放,問題就轉化為了有(n-m)個球,允許空盒,有多少種情況,容易發現這就是上面的dp[n-m][m]。
用隔板法即可解決:球之間有(n-1)個空,由於要分成m份,所以應該插(m-1)個隔板,所以方案數為c(n-1,m-1)。
可根據三推得:首先我們假設先在每個盒子裡放乙個球,然後再往任意盒中放n個球,在這個前提下,問題就轉化為共有(n+m)個球,要放到m個盒子中,不允許空盒的方案數,即c(n+m-1,m-1)。
在介紹5,6,7之前先介紹乙個小知識點:斯特林數(已經了解的可以跳過這一部分)。
第一類斯特林數
s(n,m)表示將n個不同物品排成k個非空迴圈排列的方法數。
可以舉個形象點的例子:現在有n個人要圍著m張相同圓桌坐下來,要求每張桌子非空,求方案數。
我們可以這樣考慮,對於最後乙個人:
如果他單獨坐一桌的話,結果就是剩下的(n-1)個人圍著(m-1)張圓桌而坐的方案數,即s(n-1,m-1)。
如果前面(n-1)個人已經坐了m張圓桌,這(n-1)個人的方案數為s(n-1,m),那麼最後乙個人就要插入到他們之中,他可以被安排在第乙個人或第二個人或。。。或第(n-1)個人的左邊,所以這種坐法方案數為(n-1)*s(n-1,m)。 綜上所述,就可以寫出第一類斯特林數的狀態轉移方程
s(n,m)=(n-1)*s(n-1,m)+s(n-1,m-1)
第一類斯特林數的預處理**
void init()
{ for(int i=1; i第二類斯特林數
s(n,m)表示把n個不同物品劃分到m個不可區分的盒子中且沒有空盒的方案數。
我們還是來考慮最後乙個物品,它有兩種情況
如果最後乙個物品單獨放到乙個盒子中,那麼結果就是剩下的(n-1)個物品放到(m-1)個盒子中,且盒子非的方案數,即s(n-1,m-1)。
如果前面(n-1)個物品放完後已經沒有空盒,(方案共有s(n-1,m)種),那麼最後乙個物品可以放在任意乙個中(方案共有m種),總方案數即為m*s(n-1,m)。
綜上所述,就可以寫出第二類斯特林數的狀態轉移方程
s(n,m)=m*s(n-1,m)+s(n-1,m-1)
第二類斯特林數的預處理**
void init()
{ for(int i=1; i接下來,我們便可以利用斯特林數解決問題5,6,7了。
【ps】下面用到的均為第二類斯特林數。
根據第二類斯特林數的定義,該問題就是n個不同的物品放入m個相同的箱子中且箱子不能為空,即s(n,m)。
我們只要列舉非空盒的個數(列舉範圍為1~n),可以設非空盒的個數為k,那麼每次列舉得到的方案數即為s(n,k),總方案數為s(n,1)+s(n,2)+...+s(n,m)。
對比問題七,變化的是盒子從相同變成了不同。我們可以這樣考慮,s(n,m)為把n個不同物品分成m份的方案數,現在由於盒子不同,我們只要給盒子排個順序,然後對應於m份即可,排列順序有m!種情況,故總方案數為m!*s(n,m)。
這個問題最簡單了,每個球都能任意選擇乙個盒子去放,每個球有m種情況,故總方案數為mn。
組合數學 斯特林數
斯特林數包括第一類斯特林數和第二類斯特林數 第一類斯特林數 定義 n個不同的元素構成m個圓排列 迴圈排列 的方法數 分成兩種情況 1 前n 1個元素已經構成了m個圓排列,只要將第n個元素插入1 n 1個元素中任意乙個元素的左邊即可 n 1 s n 1,m 2 前n 1個元素已經構成了m 1個圓排列,...
組合數學之斯特林數 貝爾數
斯特林數經常和組合數學中的上公升下降問題聯絡到一起。第一類斯特林數 將n個不同的元素構成m個不同的環的方案數目 兩環不想等當且僅當任一不能通過旋轉得到另一環 dp i j 表示i個元素構成j個環 有兩種情況可以得到dp i j 1.前i 1個元素構成了j 1個不同的環,第i個元素單獨成環 共有 dp...
兩類斯特林數 組合數學
斯特林數是組合數學中的乙個重要內容,有許多有用的性質.它由十八世紀的蘇格蘭數學家james stirling首先發現並說明了它們的重要性.斯特林數主要處理的是把n個不同的元素分成k個集合或環的個數問題.現在我們說的斯特林數可以指兩類數,分為第一類斯特林數和第二類斯特林數,其中第一類斯特林數還分成有符...