Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Selected Reading
Number of Dice Rolls With Target Sum in Python
The problem asks us to find the number of ways to roll d dice (each with f faces) such that the sum equals a target value. We need to return the result modulo 109 + 7.
For example, with 2 dice having 6 faces each and target sum 7, there are 6 ways: (1,6), (2,5), (3,4), (4,3), (5,2), (6,1).
Algorithm Approach
We'll use dynamic programming where dp[i][j] represents the number of ways to achieve sum j using i+1 dice ?
- Base case: For the first die, there's exactly 1 way to get any sum from 1 to f
- Transition: For each additional die, we sum up ways from previous dice states
- Result:
dp[d-1][target]gives us the answer
Implementation
def numRollsToTarget(d, f, target):
mod = 1000000007
# Create DP table: dp[i][j] = ways to get sum j using i+1 dice
dp = [[0 for _ in range(target + 1)] for _ in range(d)]
# Fill the DP table
for i in range(d):
for j in range(target + 1):
if i == 0:
# Base case: first die can show values 1 to f
dp[i][j] = 1 if 1 <= j <= f else 0
else:
# For subsequent dice, sum ways from previous dice
for face_value in range(1, f + 1):
if j - face_value > 0:
dp[i][j] += dp[i-1][j - face_value]
dp[i][j] %= mod
return dp[d-1][target] % mod
# Test the function
result = numRollsToTarget(2, 6, 7)
print("Number of ways:", result)
Number of ways: 6
How It Works
Alternative Approach: Space-Optimized
Since we only need the previous row, we can optimize space complexity ?
def numRollsToTarget_optimized(d, f, target):
mod = 1000000007
# Use only two arrays instead of 2D table
prev = [0] * (target + 1)
curr = [0] * (target + 1)
# Initialize first die
for j in range(1, min(f + 1, target + 1)):
prev[j] = 1
# Process remaining dice
for i in range(1, d):
curr = [0] * (target + 1)
for j in range(target + 1):
for face_value in range(1, f + 1):
if j - face_value > 0:
curr[j] += prev[j - face_value]
curr[j] %= mod
prev = curr[:]
return prev[target] % mod
# Test both approaches
print("Original approach:", numRollsToTarget(2, 6, 7))
print("Optimized approach:", numRollsToTarget_optimized(2, 6, 7))
Original approach: 6 Optimized approach: 6
Complexity Analysis
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| 2D DP Table | O(d × target × f) | O(d × target) |
| Space Optimized | O(d × target × f) | O(target) |
Conclusion
The dynamic programming approach efficiently solves the dice roll problem by building up solutions from smaller subproblems. The space-optimized version reduces memory usage while maintaining the same time complexity.
Advertisements
