想做只整天擼程式碼的程式狗
阿新 • • 發佈:2019-02-13
問題描述:
有n種物品,第i種物品有ai個。從這些物品中取m個,有多少種取法,求出方案數 模上M的餘數。
Sample input:
n = 3;
m=3;
a = {1,2,3};
M = 10000;
Sample output:
6 (0+0+3,0+1+2,0+2+1,1+0+2,1+1+1,1+2+0)
該題採用動態規劃。
其中有一個思想讓我感觸很深:
dp[i+1][j] := 前i種物品中取出j個物品的組合總數
那麼對於dp[i+1][j] 其中的每種取法都可以拆分為前i-1種物品取j-k件,第i種物品取k件、
那麼
dp[i+1][j] = [i][j−k]
做題的時候經常遇到這種公式,而怎麼把他轉換成動態方程,卻沒什麼思路,但是看了該題,終於有了點思路,那就是把上邊的求和公式轉變成另一個dp陣列。
即:
注意,該公式分兩種情況,一個是j-1
那麼由此得到
dp[i+1][j] = dp[i+1][j-1] + dp[i][j] - dp[i][j-1-ai]
而在寫程式碼的時候,可能遇到得到的dp數為負數,因為其中有減法運算,所以有減法運算的時候,在末尾加上M 然後再模上M,這樣能確保得到的結果不會出現負數。