SHOW:
|
|
- or go back to the newest paste.
1 | 有n层楼梯,每次可以爬1~2步,问能爬的最少的能整除 m 的步数是多少? n <= 10000, m < 20. | |
2 | ||
3 | n 小于等于一万, 用 dfs + memo 会栈溢出. | |
4 | 请问怎么把下边的 DFS + Memoization 转换成 DP 数组递推? | |
5 | ||
6 | class Solution: | |
7 | def minStep(self, n, m): | |
8 | if n < m: | |
9 | - | # DFS + memoization, |
9 | + | |
10 | # DFS + memoization, 返回最小步数, 没有就返回正无穷, 记忆数组 f 唯一索引是 (n, steps) | |
11 | f = [[-1] * (n + 1) for _ in range(n + 1)] | |
12 | ans = self.dfs(n, m, 0, f) | |
13 | if ans == float("inf"): | |
14 | return -1 | |
15 | return ans | |
16 | ||
17 | def dfs(self, n, m, steps, f): | |
18 | if n < 0: | |
19 | return float("inf") | |
20 | if n == 0: | |
21 | if steps % m == 0: | |
22 | f[n][steps] = steps | |
23 | return steps | |
24 | return float("inf") | |
25 | if f[n][steps] != -1: | |
26 | return f[n][steps] | |
27 | ans = float("inf") | |
28 | ans = min(ans, self.dfs(n - 1, m, steps + 1, f)) | |
29 | ans = min(ans, self.dfs(n - 2, m, steps + 1, f)) | |
30 | f[n][steps] = ans | |
31 | return ans | |
32 | ||
33 | - | n, m = 271, 5 |
33 | + | |
34 | - | n, m = 10, 2 |
34 | + | n, m = 271, 8 |
35 | # n, m = 10, 2 | |
36 | n, m = 1271, 7 | |
37 | - | print(ans) |
37 | + | |
38 | ans = o.minStep(n, m) | |
39 | print(ans) | |
40 | ||
41 | 动态规划思路,在所有能走到的n的步数当中,找到最小的能整出m的那一个步数。 | |
42 | 二维数组,第1维 n个台阶,第2维,走到n需要的步数。 | |
43 | ||
44 | class Solution: | |
45 | def minStep(self, n, m): | |
46 | if n < m: | |
47 | return -1 | |
48 | ||
49 | # DP, 分两步. 1. 找到能走到 n 的步数, 2. f[n] 数组里面, 从小到大找最小整除 m 的数字, 返回. | |
50 | f = [[False] * (n + 1) for _ in range(n + 1)] | |
51 | for i in range(n + 1): | |
52 | f[0][i] = True | |
53 | for i in range(1, n + 1): | |
54 | for j in range(1, i + 1): | |
55 | if f[i - 1][j - 1]: | |
56 | f[i][j] = True | |
57 | if f[i - 2][j - 1]: | |
58 | f[i][j] = True | |
59 | for i in range(n + 1): | |
60 | if f[n][i] and i % m == 0: | |
61 | return i | |
62 | return -1 |