23. Dice throw
The problem can be found at the following link: 🔗 Question Link
🧩 Problem Description
Given n dice, each having faces numbered from 1 to m, find the number of ways to get a total sum x when all the dice are thrown.
You must count every distinct sequence of face-up values (order matters).
You are given:
ndice,each having
mfaces numbered from 1 tom,and a target sum
x.
Find the number of ways to get the sum x using the n dice. The result can be large, so return it modulo 10⁹+7.
📘 Examples
Example 1:
Input:
m = 6, n = 3, x = 12Output:
Explanation:
There are 25 distinct sequences of three 6-faced dice that sum up to 12.
Example 2:
Input:
Output:
Explanation:
Only the sequence [2,2,2] sums to 6 when using three 2-faced dice.
🔒 Constraints
$1 \leq m, n, x \leq 50$
$1 \leq x \leq 2500$
✅ My Approach
Classic 2D Dynamic Programming
We use a classic bottom-up dynamic programming strategy. Let dp[i][j] represent the number of ways to get sum j using i dice.
Recurrence Relation:
To get a sum of j with i dice, try all face values k = 1...m, and add ways to get j - k with i - 1 dice:
Algorithm Steps:
Create a 2D vector
dp[n+1][x+1]and initializedp[0][0] = 1.Loop
ifrom1ton(number of dice).Loop
jfrom1tox(target sum).For each
kfrom1tom, ifj ≥ k, adddp[i-1][j-k]todp[i][j].Return
dp[n][x].
🧮 Time and Auxiliary Space Complexity
Time Complexity: O(n × x × m) We compute each state
(i, j)using up tomprevious states.Auxiliary Space Complexity: O(n × x) We use a 2D DP table with
n+1rows andx+1columns.
🧑💻 Code (C++)
⚡ Alternative Approaches
📊 2️⃣ Space Optimized DP
Instead of using a 2D table, use two 1D arrays: dp and tmp.
Algorithm Steps:
Use two 1D arrays
dpandtmp, wheredp[j]represents the number of ways to form sumjusingi-1dice.Initialize
dp[0] = 1since there's one way to reach sum 0 with 0 dice.For each die
ifrom 1 ton, do the following:Clear the
tmparray.For each target sum
jfrom 1 tox:Loop through each face value
kfrom 1 tom(andk <= j) and accumulate ways fromdp[j - k]totmp[j].
After processing a die, assign
tmptodp.Return
dp[x], which holds the number of ways to get sumxwithndice.
✅ Why This Approach?
Minimizes memory use with only two rows (1D arrays).
Retains full accuracy and efficiency of 2D dynamic programming.
Especially useful for large
nandx.
📝 Complexity Analysis:
Time: O(n × x × m) — Three nested loops for each die, each sum, and each face.
Auxiliary Space: O(x) — Only two 1D arrays of size
x + 1are used.
📊 3️⃣ Recursive + Memoization
Algorithm Steps:
Algorithm Steps:
Use recursion to simulate choosing each face for every die.
At each recursive call:
If
n == 0, return 1 ifx == 0, else return 0.If
x < 0, return 0 (invalid state).Use memoization to store and reuse previously computed results.
Try all face values from 1 to
mand recurse withn - 1dice andx - face.
✅ Why This Approach?
Naturally expresses the problem as a recursive decision tree.
Easy to understand, especially when learning recursion + memoization.
Less control over performance and higher overhead due to recursion stack.
📝 Complexity Analysis:
Time: O(n × x × m) — Each state
(n, x)is computed once with up tomchoices.Auxiliary Space: O(n × x) — For memoization + recursion stack.
🆚 Comparison of Approaches
Approach
⏱️ Time
🗂️ Space
✅ Pros
⚠️ Cons
📈 Classic 2D DP
🟢 O(n·x·m)
🔸 O(n·x)
Easy to understand and implement
More space than needed
➿ Space-Optimized DP
🟢 O(n·x·m)
🟢 O(x)
Fast and memory-efficient
Slightly less intuitive
🔁 Recursive + Memoization
🟢 O(n·x·m)
🔸 O(n·x)
Good for learning and debugging
Stack overflow risk for large n
✅ Best Choice by Scenario
Scenario
Recommended Approach
🏆 Minimize both time & memory
🥇 Space-Optimized DP
📚 Simplicity and clarity
🥈 Classic 2D DP
💡 Recursive problem-solving focus
🥉 Recursive + Memoization
🧑💻 Code (Java)
🐍 Code (Python)
🧠 Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: 📬 Any Questions?. Let’s make this learning journey more collaborative!
⭐ If you find this helpful, please give this repository a star! ⭐
📍Visitor Count
Last updated