See 数位 DP 通用模板,附题单(Python/Java/C++/Go).

233. Number of Digit One

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def countDigitOne(self, n: int) -> int:
s = str(n)
@cache
def f(i: int, cnt1: int, is_limit: bool) -> int:
if i == len(s):
return cnt1
res = 0
up = int(s[i]) if is_limit else 9
for d in range(up + 1):
res += f(i + 1, cnt1 + (d == 1), is_limit and d == up)
return res
return f(0, 0, True)

2719. Count of Integers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
def count(self, num1: str, num2: str, min_sum: int, max_sum: int) -> int:
n = len(num2)
num1 = num1.zfill(n)

@cache
def dfs(i: int, s: int, limit_low: bool, limit_high: bool) -> int:
if s > max_sum:
return 0
if i == n:
return s >= min_sum

lo = int(num1[i]) if limit_low else 0
hi = int(num2[i]) if limit_high else 9
res = 0
for d in range(lo, hi + 1):
res += dfs(i + 1, s + d, limit_low and d == lo, limit_high and d == hi)
return res

return dfs(0, 0, True, True) % 1_000_000_007

788. Rotated Digits

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DIFFS = (0, 0, 1, -1, -1, 1, 1, -1, 0, 1)
class Solution:
def rotatedDigits(self, n: int) -> int:
s = str(n)
@cache
def f(i: int, has_diff: bool, is_limit: bool) -> int:
if i == len(s):
return has_diff
res = 0
up = int(s[i]) if is_limit else 9
for d in range(0, up + 1):
if DIFFS[d] != -1:
res += f(i + 1, has_diff or DIFFS[d], is_limit and d == up)
return res
return f(0, False, True)

902. Numbers At Most N Given Digit Set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution:
def atMostNGivenDigitSet(self, digits: List[str], n: int) -> int:
s = str(n)
@cache
def f(i: int, is_limit: bool, is_num: bool) -> int:
if i == len(s):
return int(is_num)
res = 0
if not is_num:
res = f(i + 1, False, False)
# no need coz digits[i] != 0
# low = 0 if is_num else 1
up = s[i] if is_limit else '9'
for d in digits:
if d > up:
break
res += f(i + 1, is_limit and d == up, True)
return res
return f(0, True, False)

2376. Count Special Integers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution:
def countSpecialNumbers(self, n: int) -> int:
s = str(n)
@cache
def f(i: int, mask: int, is_limit: bool, is_num: bool) -> int:
if i == len(s):
return int(is_num)
res = 0
if not is_num:
res = f(i + 1, mask, False, False)
low = 0 if is_num else 1
up = int(s[i]) if is_limit else 9
for d in range(low, up + 1):
if (mask >> d & 1) == 0:
res += f(i + 1, mask | (1 << d), is_limit and d == up, True)
return res
return f(0, 0, True, False)

600. Non-negative Integers without Consecutive Ones

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def findIntegers(self, n: int) -> int:
s = str(bin(n))[2:]
@cache
def f(i: int, pre1: bool, is_limit: bool) -> int:
if i == len(s):
return 1
up = int(s[i]) if is_limit else 1
res = f(i + 1, False, is_limit and up == 0)
if not pre1 and up == 1:
res += f(i + 1, True, is_limit)
return res
return f(0, False, True)

1012. Numbers With Repeated Digits

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution:
def numDupDigitsAtMostN(self, n: int) -> int:
s = str(n)
@cache
def f(i: int, mask: int, is_limit: bool, is_num: bool) -> int:
if i == len(s):
return int(is_num)
res = 0
if not is_num:
res = f(i + 1, mask, False, False)
low = 0 if is_num else 1
up = int(s[i]) if is_limit else 9
for d in range(low, up + 1):
if (mask >> d & 1) == 0:
res += f(i + 1, mask | (1 << d), is_limit and d == up, True)
return res
return n - f(0, 0, True, False)

357. Count Numbers with Unique Digits

1

3007. Maximum Number That Sum of the Prices Is Less Than or Equal to K

1

2827. Number of Beautiful Integers in the Range

1

2999. Count the Number of Powerful Integers

1

2801. Count Stepping Numbers in Range

1

See 两种 Dijkstra 写法(附题单)Python/Java/C++/Go/JS/Rust.

743. Network Delay Time

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution:
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
g = [[] for _ in range(n)]
for x, y, d in times:
g[x - 1].append((y - 1, d))
dis = [inf] * n
dis[k - 1] = 0
h = [(0, k - 1)]
while h:
dx, x = heappop(h)
if dx > dis[x]:
continue
for y, d in g[x]:
new_dis = dx + d
if new_dis < dis[y]:
dis[y] = new_dis
heappush(h, (new_dis, y))
mx = max(dis)
return mx if mx < inf else -1
Read more »

See 线性 DP,附相似题目(Python/Java/C++/Go)

2830. Maximize the Profit as the Salesman

1
2
3
4
5
6
7
8
9
10
11
class Solution:
def maximizeTheProfit(self, n: int, offers: List[List[int]]) -> int:
groups = [[] for _ in range(n)]
for start, end, gold in offers:
groups[end].append((start, gold))
f = [0] * (n + 1)
for end, g in enumerate(groups):
f[end + 1] = f[end]
for start, gold in g:
f[end + 1] = max(f[end + 1], f[start] + gold)
return f[n]

2008. Maximum Earnings From Taxi

1
2
3
4
5
6
7
8
9
10
11
class Solution:
def maxTaxiEarnings(self, n: int, rides: List[List[int]]) -> int:
groups = [[] for _ in range(n)]
for start, end, tip in rides:
groups[end - 1].append((start - 1, end - start + tip))
f = [0] * (n + 1)
for end, g in enumerate(groups):
f[end + 1] = f[end]
for start, profit in g:
f[end + 1] = max(f[end + 1], f[start + 1] + profit)
return f[n]
Read more »
0%