多重集組合計數

2021-07-05 02:38:38 字數 1468 閱讀 7414

n 種物品,第 i 種物品有ai

個。不區分同類物品,從中取出 m 個,問有多少種取法(答案取模109

+7)。1≤

n≤1000 1

≤m≤1000 1

≤ai≤

1000

dp[i][j] 表示前面 i 種物品,取出 j 個的取法數目。考察第 i 種物品取了 k 個(0≤

k≤min(ai

,j) ),那麼在剩下的 i - 1 種物品中就要取出 j - k 個。

所以: dp

[i][

j]=∑

k=0min(j

,ai)

dp[i

−1][

j−k]

最後結果是 dp[n][m]。

直接計算是o(

nm2)

的。注意到 dp 陣列的第 i 行的第 j 個是前面一行的連續部分的和,我們考慮處理字尾和: su

m[i]

[j]=

∑k=j

mdp[

i][j

] 那麼: dp

[i][

j]su

m[i]

[j]=

sum[

i−1]

[j−m

in(j

,ai)

]−su

m[i−

1][j

+1];

=sum

[i][

j+1]

+dp[

i][j

];之所以要處理字尾和而不是字首和是因為這樣不用特判斷邊界。

另外,考察上面的規劃順序,i 迴圈應該是增順序,j 迴圈應該是減順序,先 i 後 j。

同樣考慮到第 i 行的第 j 個是前面一行的連續部分的和,我們應該認識到 dp[i][j] 和 dp[i][j - 1] 應該是大部分相同的。

為此我們計算: dp

[i][

j]=∑

k=0min(j

,ai)

dp[i

−1][

j−k]

−dp[

i][j

−1]−

∑k=0

min(j−

1,ai

)dp[

i−1]

[j−1

−k]

經過對min

(...

) 的取值討論之後,我們得到: dp

[i][

j]−d

p[i]

[j−1

]={d

p[i−

1][j

]−dp

[i−1

][j−

1−ai

],dp

[i−1

][j]

,j−1

≥aio

ther

wise

這樣也可以 o(

nm) 時間內解決這個問題。

多重集組合數

問題描述 有n種物品,第i種物品有ai個。從這些物品中取m個,有多少種取法,求出方案數 模上m的餘數。sample input n 3 m 3 a m 10000 sample output 6 0 0 3,0 1 2,0 2 1,1 0 2,1 1 1,1 2 0 該題採用動態規劃。其中有乙個思想...

多重集組合數

題述 有n種物品,第i種物品有ai個。不同種類的物品可以互相區分但相同種類的無法區分。從這些物品中取出m個的話,有多少種取法?求出方案數模m的餘數。限制條件 1 n 1000 1 m 1000 1 ai 1000 2 m 10000 樣例 輸入3 5 1 2 3 10000輸出6 題記 dp i 1...

計數dp 劃分數 多重集組合數

劃分數 把n個無區別的物品劃分成不超過m組。dp i j j的i劃分的總數。dp i j dp i j i dp i 1 j 即 將j個物品分成i份,有兩種情況 每份劃分都大於等於1 dp i j i 存在有乙份以上用0劃分dp i 1 j int main cout 0 多重集組合數 n種物品,第...