Browse curriculum

Digit DP

Digit DP is a technique to count integers in a range [0, N] that satisfy a specific property (e.g., no digit 4).

LIMIT

Target

2
0

Digit

0
1
2
3
4
5
6
7
8
9

Found (0)

—

 

Pos 0: Tight=true, Limit=2. Exploring digits 0-2...

Next

Trying digit 0...

N

Max 100

Intuition

Counting numbers one by one is too slow if N is large (e.g., 1018). Instead, we "construct" the numbers digit by digit from left to right. This allows us to count huge ranges in logarithmic time O(log N).

Concept

State representation:

  • pos: Current digit position we are filling (from left).
  • tight: Boolean. If true, we are restricted by the digits of N. We can place digits from 0 to N[pos]. If false, we can place any digit 0-9.
  • valid: (Optional) Tracks if the property is maintained.

Memoization: We store results for dp[pos][tight][state] to avoid re-calculation.

How it Works

Algorithm:

  1. Convert N to a string or array of digits.
  2. Start recursion from the first digit with tight = true.
  3. At each step pos, iterate through possible digits d from 0 to limit (where limit is N[pos] if tight is true, else 9).
  4. Update tight for the next state: newTight = tight && (d == limit).
  5. Sum up the results from valid recursive calls.

Step-by-Step Breakdown

Visualizing the Construction:

  • Root: Start at most significant digit.
  • Branches: Each branch is a choice of a digit (0..9).
  • Pruning: Branches that violate the property are cut off.
  • Aggregation: Leaf nodes (valid numbers) contribute 1 to the count.

When to Use

Applications:

  • Counting integers in large ranges (up to 1018).
  • Properties related to digits (sum of digits, specific digits, palindromes).

When NOT to Use

  • Small Range: If N is small, simple iteration is faster and simpler.
  • Non-Digit Properties: Properties like "divisible by X" (though sometimes possible with extra state) are harder.

How to Identify

"Count numbers between L and R satisfying...", "Digit sum equals K".

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description

Frequently Asked Questions

What is the tight flag for?

It records whether the digits chosen so far still match the prefix of the bound N. While tight, the next digit is capped at the digit N has in that position; once a smaller digit is placed the remaining positions are free to use 0-9.


Why memoise on position and tightness rather than on the number?

Because the numbers reach 10^18 and cannot be enumerated, while the state space is only about 19 positions times 2 tightness values times the property state. That is a few hundred states no matter how large N is.


How do I count over a range [L, R]?

Solve the prefix form f(X), the count of valid numbers in [0, X], and take f(R) - f(L-1). Digit DP counts upward from zero, so every range query reduces to two calls.