|
61 | 61 |
|
62 | 62 | <!-- 这里可写通用的实现逻辑 -->
|
63 | 63 |
|
| 64 | +**方法一:记忆化搜索** |
| 65 | + |
| 66 | +我们先根据题目给定的边构建图 $g$,其中 $g[i]$ 表示节点 $i$ 的所有邻接节点。然后我们可以使用记忆化搜索的方法求解本题。 |
| 67 | + |
| 68 | +我们设计一个函数 $dfs(i, fa, j)$,表示当前节点为 $i$,父节点为 $fa$,当前节点的金币数需要右移 $j$ 位,所能获得的最大积分。 |
| 69 | + |
| 70 | +函数 $dfs(i, fa, j)$ 的执行过程如下: |
| 71 | + |
| 72 | +如果我们使用第一种方法收集当前节点的金币,那么当前节点的积分为 $(coins[i] >> j) - k$,然后我们遍历当前节点的所有邻接节点 $c$,如果 $c$ 不等于 $fa$,那么我们将 $dfs(c, i, j)$ 的结果累加到当前节点的积分中。 |
| 73 | + |
| 74 | +如果我们使用第二种方法收集当前节点的金币,那么当前节点的积分为 $coins[i] >> (j + 1)$,然后我们遍历当前节点的所有邻接节点 $c$,如果 $c$ 不等于 $fa$,那么我们将 $dfs(c, i, j + 1)$ 的结果累加到当前节点的积分中。注意,由于题目中给定的 $coins[i]$ 最大值为 $10^4$,因此我们最多只能右移 $14$ 位,就使得 $coins[i] >> (j + 1)$ 的值为 $0$。 |
| 75 | + |
| 76 | +最后,我们返回当前节点使用两种方法中能获得的最大积分。 |
| 77 | + |
| 78 | +为了避免重复计算,我们使用记忆化搜索的方法,将 $dfs(i, fa, j)$ 的结果存储到 $f[i][j]$ 中,其中 $f[i][j]$ 表示当前节点为 $i$,父节点为 $fa$,当前节点的金币数需要右移 $j$ 位,所能获得的最大积分。 |
| 79 | + |
| 80 | +时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n \times \log M)$。其中 $M$ 表示 $coins[i]$ 的最大值。 |
| 81 | + |
64 | 82 | <!-- tabs:start -->
|
65 | 83 |
|
66 | 84 | ### **Python3**
|
67 | 85 |
|
68 | 86 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
69 | 87 |
|
70 | 88 | ```python
|
71 |
| - |
| 89 | +class Solution: |
| 90 | + def maximumPoints(self, edges: List[List[int]], coins: List[int], k: int) -> int: |
| 91 | + @cache |
| 92 | + def dfs(i: int, fa: int, j: int) -> int: |
| 93 | + a = (coins[i] >> j) - k |
| 94 | + b = coins[i] >> (j + 1) |
| 95 | + for c in g[i]: |
| 96 | + if c != fa: |
| 97 | + a += dfs(c, i, j) |
| 98 | + if j < 14: |
| 99 | + b += dfs(c, i, j + 1) |
| 100 | + return max(a, b) |
| 101 | + |
| 102 | + n = len(coins) |
| 103 | + g = [[] for _ in range(n)] |
| 104 | + for a, b in edges: |
| 105 | + g[a].append(b) |
| 106 | + g[b].append(a) |
| 107 | + ans = dfs(0, -1, 0) |
| 108 | + dfs.cache_clear() |
| 109 | + return ans |
72 | 110 | ```
|
73 | 111 |
|
74 | 112 | ### **Java**
|
75 | 113 |
|
76 | 114 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
77 | 115 |
|
78 | 116 | ```java
|
79 |
| - |
| 117 | +class Solution { |
| 118 | + private int k; |
| 119 | + private int[] coins; |
| 120 | + private Integer[][] f; |
| 121 | + private List<Integer>[] g; |
| 122 | + |
| 123 | + public int maximumPoints(int[][] edges, int[] coins, int k) { |
| 124 | + this.k = k; |
| 125 | + this.coins = coins; |
| 126 | + int n = coins.length; |
| 127 | + f = new Integer[n][15]; |
| 128 | + g = new List[n]; |
| 129 | + Arrays.setAll(g, i -> new ArrayList<>()); |
| 130 | + for (var e : edges) { |
| 131 | + int a = e[0], b = e[1]; |
| 132 | + g[a].add(b); |
| 133 | + g[b].add(a); |
| 134 | + } |
| 135 | + return dfs(0, -1, 0); |
| 136 | + } |
| 137 | + |
| 138 | + private int dfs(int i, int fa, int j) { |
| 139 | + if (f[i][j] != null) { |
| 140 | + return f[i][j]; |
| 141 | + } |
| 142 | + int a = (coins[i] >> j) - k; |
| 143 | + int b = coins[i] >> (j + 1); |
| 144 | + for (int c : g[i]) { |
| 145 | + if (c != fa) { |
| 146 | + a += dfs(c, i, j); |
| 147 | + if (j < 14) { |
| 148 | + b += dfs(c, i, j + 1); |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | + return f[i][j] = Math.max(a, b); |
| 153 | + } |
| 154 | +} |
80 | 155 | ```
|
81 | 156 |
|
82 | 157 | ### **C++**
|
83 | 158 |
|
84 | 159 | ```cpp
|
85 |
| - |
| 160 | +class Solution { |
| 161 | +public: |
| 162 | + int maximumPoints(vector<vector<int>>& edges, vector<int>& coins, int k) { |
| 163 | + int n = coins.size(); |
| 164 | + int f[n][15]; |
| 165 | + memset(f, -1, sizeof(f)); |
| 166 | + vector<int> g[n]; |
| 167 | + for (auto& e : edges) { |
| 168 | + int a = e[0], b = e[1]; |
| 169 | + g[a].emplace_back(b); |
| 170 | + g[b].emplace_back(a); |
| 171 | + } |
| 172 | + function<int(int, int, int)> dfs = [&](int i, int fa, int j) { |
| 173 | + if (f[i][j] != -1) { |
| 174 | + return f[i][j]; |
| 175 | + } |
| 176 | + int a = (coins[i] >> j) - k; |
| 177 | + int b = coins[i] >> (j + 1); |
| 178 | + for (int c : g[i]) { |
| 179 | + if (c != fa) { |
| 180 | + a += dfs(c, i, j); |
| 181 | + if (j < 14) { |
| 182 | + b += dfs(c, i, j + 1); |
| 183 | + } |
| 184 | + } |
| 185 | + } |
| 186 | + return f[i][j] = max(a, b); |
| 187 | + }; |
| 188 | + return dfs(0, -1, 0); |
| 189 | + } |
| 190 | +}; |
86 | 191 | ```
|
87 | 192 |
|
88 | 193 | ### **Go**
|
89 | 194 |
|
90 | 195 | ```go
|
| 196 | +func maximumPoints(edges [][]int, coins []int, k int) int { |
| 197 | + n := len(coins) |
| 198 | + f := make([][]int, n) |
| 199 | + for i := range f { |
| 200 | + f[i] = make([]int, 15) |
| 201 | + for j := range f[i] { |
| 202 | + f[i][j] = -1 |
| 203 | + } |
| 204 | + } |
| 205 | + g := make([][]int, n) |
| 206 | + for _, e := range edges { |
| 207 | + a, b := e[0], e[1] |
| 208 | + g[a] = append(g[a], b) |
| 209 | + g[b] = append(g[b], a) |
| 210 | + } |
| 211 | + var dfs func(int, int, int) int |
| 212 | + dfs = func(i, fa, j int) int { |
| 213 | + if f[i][j] != -1 { |
| 214 | + return f[i][j] |
| 215 | + } |
| 216 | + a := (coins[i] >> j) - k |
| 217 | + b := coins[i] >> (j + 1) |
| 218 | + for _, c := range g[i] { |
| 219 | + if c != fa { |
| 220 | + a += dfs(c, i, j) |
| 221 | + if j < 14 { |
| 222 | + b += dfs(c, i, j+1) |
| 223 | + } |
| 224 | + } |
| 225 | + } |
| 226 | + f[i][j] = max(a, b) |
| 227 | + return f[i][j] |
| 228 | + } |
| 229 | + return dfs(0, -1, 0) |
| 230 | +} |
| 231 | +``` |
91 | 232 |
|
| 233 | +### **TypeScript** |
| 234 | + |
| 235 | +```ts |
| 236 | +function maximumPoints(edges: number[][], coins: number[], k: number): number { |
| 237 | + const n = coins.length; |
| 238 | + const f: number[][] = Array.from({ length: n }, () => Array(15).fill(-1)); |
| 239 | + const g: number[][] = Array.from({ length: n }, () => []); |
| 240 | + for (const [a, b] of edges) { |
| 241 | + g[a].push(b); |
| 242 | + g[b].push(a); |
| 243 | + } |
| 244 | + const dfs = (i: number, fa: number, j: number): number => { |
| 245 | + if (f[i][j] !== -1) { |
| 246 | + return f[i][j]; |
| 247 | + } |
| 248 | + let a = (coins[i] >> j) - k; |
| 249 | + let b = coins[i] >> (j + 1); |
| 250 | + for (const c of g[i]) { |
| 251 | + if (c !== fa) { |
| 252 | + a += dfs(c, i, j); |
| 253 | + if (j < 14) { |
| 254 | + b += dfs(c, i, j + 1); |
| 255 | + } |
| 256 | + } |
| 257 | + } |
| 258 | + return (f[i][j] = Math.max(a, b)); |
| 259 | + }; |
| 260 | + return dfs(0, -1, 0); |
| 261 | +} |
92 | 262 | ```
|
93 | 263 |
|
94 | 264 | ### **...**
|
|
0 commit comments