Skip to main content
  1. LeetCode/

LeetCode 1155: Number of Dice Rolls With Target Sum

·3 mins· ·
LeetCode Medium Dynamic-Programming Counting
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-08-23 Source: Day 44 learning note

Study Context
#

This article is rebuilt from the exact LeetCode section in the learning note. I kept the note’s repair points, comparison points, and common mistakes, while removing unrelated non-LeetCode material from the same day.

Related Reminders From The Note#

  • LC 1155: pass after state and base-case repair
  • explain why LC 1155 needs per-die layers and newDp
  • say one clean difference between LC 494, LC 518, and LC 1155

Learning Note Extract
#

Problem 2 - LC 1155 Number of Dice Rolls With Target Sum
#

  • Pattern: layered counting DP with bounded per-step choices.

Why This Fits
#

This is not subset choice and not unbounded reuse.

The real question is:

after rolling exactly d dice, how many ways produce sum s?

Core State / Invariant
#

2D form:

dp[d][s] = number of ways to make sum s using exactly d dice

Compressed form:

dp[s] = number of ways from the previous dice layer
newDp[s] = number of ways for the current dice layer

Base Case
#

Before rolling any dice:

dp[0] = 1

Reason:

there is exactly one way to make sum 0 with 0 dice

Transition
#

For each die, for each target sum, try every face:

newDp[s] += dp[s - face]

when:

s - face >= 0

Apply modulo after each addition.

Why newDp Is Required
#

The current layer must only read:

states from d - 1 dice

If updated in place, one die could contribute multiple times in the same layer, which is incorrect.

Complexity
#

Time: O(n * target * k)
Space: O(target)

Common Mistakes
#

  • wrong base-case explanation for dp[0]
  • trying to reuse a single array in place like LC 518
  • saying this is unbounded knapsack
  • forgetting modulo in the recurrence

Strong Spoken Explanation
#

I model this as counting ways by dice layer. dp[s] means the number of ways to make sum s from the previous number of dice, and for each new die I build a fresh newDp. For each target sum and each face value from 1 to k, I add the number of ways to reach s - face from the previous layer. The key invariant is that when computing the layer for d dice, I must only read states from d - 1 dice, which is why I use newDp instead of in-place updates.

Clean Solution
#

The note above captures the reasoning and the mistakes to avoid. The implementation below is the version I would submit.

class Solution:
    def numRollsToTarget(self, n: int, k: int, target: int) -> int:
        mod = 10 ** 9 + 7
        dp = [0] * (target + 1)
        dp[0] = 1

        for _ in range(n):
            ndp = [0] * (target + 1)
            for s in range(target + 1):
                if dp[s] == 0:
                    continue
                for face in range(1, k + 1):
                    if s + face <= target:
                        ndp[s + face] = (ndp[s + face] + dp[s]) % mod
            dp = ndp

        return dp[target]

Complexity
#

Time O(n * target * k), Space O(target).

Mistakes To Watch
#

  • Updating one array in place and mixing dice layers.
  • Forgetting the modulo.

Final Interview Explanation
#

Start from the state definition, then explain why the transition preserves that state. If there is a loop direction, state compression, or a similar-looking problem with a different answer shape, call that out explicitly because that is where this problem family usually breaks down.

Related

LeetCode 416: Partition Equal Subset Sum
·3 mins
LeetCode Medium Dynamic-Programming Knapsack Subset-Sum
LeetCode note for Partition Equal Subset Sum, rebuilt from the original learning note
LeetCode 494: Target Sum
·3 mins
LeetCode Medium Dynamic-Programming Knapsack Subset-Sum
LeetCode note for Target Sum, rebuilt from the original learning note
LeetCode 518: Coin Change 2
·3 mins
LeetCode Medium Dynamic-Programming Unbounded-Knapsack
LeetCode note for Coin Change 2, rebuilt from the original learning note
LeetCode 1049: Last Stone Weight II
·3 mins
LeetCode Medium Dynamic-Programming Knapsack Subset-Sum
LeetCode note for Last Stone Weight II, rebuilt from the original learning note
LeetCode 474: Ones and Zeroes
·3 mins
LeetCode Medium Dynamic-Programming Knapsack
LeetCode note for Ones and Zeroes, rebuilt from the original learning note
LeetCode 97: Interleaving String
·4 mins
LeetCode Medium Dynamic-Programming String
LeetCode note for Interleaving String, rebuilt from the original learning note