templates/digit-dp.cpp
compilable
$cat templates/digit-dp
Digit DP
Count numbers in [L, R] satisfying digit-level constraints using memoized recursion.
#digit-dp#dp#counting#memoization
Log in to track progress, save custom versions, and organize into collections.Log In
$cat source_code/
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll dp[20][2][2][10];
string num;
ll solve(int idx, bool tight, bool started, int last) {
if (idx == (int)num.size())
return started ? 1 : 0;
ll& ret = dp[idx][tight][started][last];
if (~ret) return ret;
ret = 0;
int lim = tight ? num[idx] - '0' : 9;
for (int d = 0; d <= lim; d++) {
bool nt = tight && (d == lim);
bool ns = started || (d != 0);
// add your constraint check here
ret += solve(idx + 1, nt, ns, ns ? d : 0);
}
return ret;
}
ll count(ll x) {
if (x < 0) return 0;
num = to_string(x);
memset(dp, -1, sizeof dp);
return solve(0, true, false, 0);
}
ll countRange(ll l, ll r) {
return count(r) - count(l - 1);
}33 linesutf-8
$cat explanation_notes.md
notes_viewer --renderedmarkdown (math enabled)
Digit DP
Counts numbers in satisfying digit-level properties without iterating every number.
Core Idea
State
idx — current digit position (0 = most significant)tight — are all digits so far equal to 's prefix? If true, next digit capped by ; if false, any digit – allowedstarted — has a nonzero digit been placed? (handles leading zeros)