You have d dice, and each die has f faces numbered 1, 2, …, f.
Return the number of possible ways (out of fd total ways) modulo 10^9 + 7 > to roll the dice so the sum of the face up numbers equals target.
Input: d = 1, f = 6, target = 3
Output: 1
Input: d = 2, f = 6, target = 7
Output: 6
Input: d = 2, f = 5, target = 10
Output: 1
Input: d = 1, f = 2, target = 3
Output: 0
Input: d = 30, f = 30, target = 500
Output: 222616187
就是用 d 個骰子(1 到 f 爲面值)能組合出朝上面 sum == target 的所有排列數(因爲要考慮順序,1 + 6 = 7 和 6 + 1 = 7 是兩種)。
每個骰子之間其實是沒有關係的,用 i
個骰子能組合出 1
到 i * f
這麼多種 sum。我們用一個二維 dp 數組記錄,dp[i][j] 表示用 i 個骰子 sum 爲 j 的可能情況數,最後結果就是 dp[d][target]:
int numRollsToTarget(int d, int f, int target) {
const int MODULE = 1e9 + 7;
if (d * f < target) return 0;
// dp[i][j] 表示用 i 個骰子sum出 j 的可能情況數
vector<vector<int>> dp(d + 1, vector<int>(target + 1, 0));
for (int j = 1; j <= min(target, f); ++j)
dp[1][j] = 1;
for(int i = 2; i <= d; ++i)
for (int j = 1; j <= min(i * f, target); ++j) // 用i個骰子最大sum就是i*f
for (int k = 1; j - k >= 1 && k <= f; ++k)
dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MODULE;
return dp[d][target];
}