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種物品,第...