問題(重複組み合わせ)
$ n $ 種類の品物があり、 $ i $ 番目の品物は $ a_i $ 個あります。
異なる種類の品物同士は区別できますが、同じ種類の品物同士は区別できません。
これらの品物の中から $ m $ 個選ぶ組み合わせの総数を求めて下さい。
[制約]
🔹$ 1 \leqq n \leqq 1000 $
🔹$ 1 \leqq m \leqq 1000 $
🔹$ 1 \leqq a_i \leqq 1000 $
解き方・ソースコード
重複なく数え上げるために、同じ種類の品物を一度に処理します。
漸化式を次のように定義します。
$$ dp[i+1][j] := i 番目までの品物からj個選ぶ組み合わせの総数 $$
$ i $ 番目までの品物から $ j $ 個選ぶためには、$ i - 1 $ 番目までの品物から $ j - k $ 個選んで、$ i $ 番目の品物を $ k $ 加えればよいので
$$ dp[i+1][j] = \sum_{k=0}^{min(j,a[i])}dp[i][j-k] $$
という漸化式が成り立ちます。
この漸化式は計算量が $ O(nm^2) $ となりますが、
$$ \sum_{k=0}^{min(j,a[i])}dp[i][j-k] = \sum_{k=0}^{min(j-1,a[i])}dp[i][j-1-k]+dp[i][j]-dp[i][j-1-a_i] $$
であるので、
$$ dp[i+1][j]=dp[i+1][j-1] + dp[i][j]-dp[i][j-1-a_i] $$
と変形することができ、計算量は$ O(nm) $ となります。
[Google Colaboratory]
1 | #--------- 入力例 ---------- |
[実行結果]
解: 6
[1 2 0]、[1 1 1]、[1 0 2]、[0 2 1]、[0 1 2]、[0 0 3]の6パターンあるので、解は6となります。