|
46 | 46 |
|
47 | 47 | <!-- 这里可写通用的实现逻辑 -->
|
48 | 48 |
|
| 49 | +**方法一:DFS + 动态规划** |
| 50 | + |
| 51 | +首先通过 DFS 构造出所有合法的排列。然后所有排列进行两两比较,找出每种排列相邻的合法排列,记录在 `g` 数组中。 |
| 52 | + |
| 53 | +然后进行动态规划。 |
| 54 | + |
| 55 | +过程是这样的:计算以某种排列结束的所有方案数。 |
| 56 | + |
| 57 | +初始化第一排每种排列的方案数为 1;每一排选取某种排列的总方案数为上一排能与自己相邻的排列的方案数之和。 |
| 58 | + |
| 59 | +答案为最后一排的方案数之和。 |
| 60 | + |
49 | 61 | <!-- tabs:start -->
|
50 | 62 |
|
51 | 63 | ### **Python3**
|
52 | 64 |
|
53 | 65 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
54 | 66 |
|
55 | 67 | ```python
|
| 68 | +class Solution: |
| 69 | + def buildWall(self, height: int, width: int, bricks: List[int]) -> int: |
| 70 | + def dfs(v): |
| 71 | + if v > width: |
| 72 | + return |
| 73 | + if v == width: |
| 74 | + s.append(t[:]) |
| 75 | + return |
| 76 | + for x in bricks: |
| 77 | + t.append(x) |
| 78 | + dfs(v + x) |
| 79 | + t.pop() |
| 80 | + |
| 81 | + def check(a, b): |
| 82 | + s1, s2 = a[0], b[0] |
| 83 | + i = j = 1 |
| 84 | + while i < len(a) and j < len(b): |
| 85 | + if s1 == s2: |
| 86 | + return False |
| 87 | + if s1 < s2: |
| 88 | + s1 += a[i] |
| 89 | + i += 1 |
| 90 | + else: |
| 91 | + s2 += b[j] |
| 92 | + j += 1 |
| 93 | + return True |
56 | 94 |
|
| 95 | + mod = 10**9 + 7 |
| 96 | + s = [] |
| 97 | + t = [] |
| 98 | + dfs(0) |
| 99 | + g = defaultdict(list) |
| 100 | + n = len(s) |
| 101 | + for i in range(n): |
| 102 | + if check(s[i], s[i]): |
| 103 | + g[i].append(i) |
| 104 | + for j in range(i + 1, n): |
| 105 | + if check(s[i], s[j]): |
| 106 | + g[i].append(j) |
| 107 | + g[j].append(i) |
| 108 | + dp = [[0] * n for _ in range(height)] |
| 109 | + for j in range(n): |
| 110 | + dp[0][j] = 1 |
| 111 | + for i in range(1, height): |
| 112 | + for j in range(n): |
| 113 | + for k in g[j]: |
| 114 | + dp[i][j] += dp[i - 1][k] |
| 115 | + dp[i][j] %= mod |
| 116 | + return sum(dp[-1]) % mod |
57 | 117 | ```
|
58 | 118 |
|
59 | 119 | ### **Java**
|
60 | 120 |
|
61 | 121 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
62 | 122 |
|
63 | 123 | ```java
|
| 124 | +class Solution { |
| 125 | + private List<List<Integer>> res = new ArrayList<>(); |
| 126 | + private List<Integer> t = new ArrayList<>(); |
| 127 | + private static final int MOD = (int) 1e9 + 7; |
| 128 | + private int width; |
| 129 | + private int[] bricks; |
| 130 | + |
| 131 | + public int buildWall(int height, int width, int[] bricks) { |
| 132 | + this.width = width; |
| 133 | + this.bricks = bricks; |
| 134 | + dfs(0); |
| 135 | + int n = res.size(); |
| 136 | + List<Integer>[] g = new List[n]; |
| 137 | + for (int i = 0; i < g.length; ++i) { |
| 138 | + g[i] = new ArrayList<>(); |
| 139 | + } |
| 140 | + for (int i = 0; i < n; ++i) { |
| 141 | + if (check(res.get(i), res.get(i))) { |
| 142 | + g[i].add(i); |
| 143 | + } |
| 144 | + for (int j = i + 1; j < n; ++j) { |
| 145 | + if (check(res.get(i), res.get(j))) { |
| 146 | + g[i].add(j); |
| 147 | + g[j].add(i); |
| 148 | + } |
| 149 | + } |
| 150 | + } |
| 151 | + int[][] dp = new int[height][n]; |
| 152 | + for (int j = 0; j < n; ++j) { |
| 153 | + dp[0][j] = 1; |
| 154 | + } |
| 155 | + for (int i = 1; i < height; ++i) { |
| 156 | + for (int j = 0; j < n; ++j) { |
| 157 | + for (int k : g[j]) { |
| 158 | + dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD; |
| 159 | + } |
| 160 | + } |
| 161 | + } |
| 162 | + int ans = 0; |
| 163 | + for (int j = 0; j < n; ++j) { |
| 164 | + ans = (ans + dp[height - 1][j]) % MOD; |
| 165 | + } |
| 166 | + return ans; |
| 167 | + } |
| 168 | + |
| 169 | + private boolean check(List<Integer> a, List<Integer> b) { |
| 170 | + int s1 = a.get(0); |
| 171 | + int s2 = b.get(0); |
| 172 | + int i = 1, j = 1; |
| 173 | + while (i < a.size() && j < b.size()) { |
| 174 | + if (s1 == s2) { |
| 175 | + return false; |
| 176 | + } |
| 177 | + if (s1 < s2) { |
| 178 | + s1 += a.get(i++); |
| 179 | + } else { |
| 180 | + s2 += b.get(j++); |
| 181 | + } |
| 182 | + } |
| 183 | + return true; |
| 184 | + } |
| 185 | + |
| 186 | + private void dfs(int v) { |
| 187 | + if (v > width) { |
| 188 | + return; |
| 189 | + } |
| 190 | + if (v == width) { |
| 191 | + res.add(new ArrayList<>(t)); |
| 192 | + return; |
| 193 | + } |
| 194 | + for (int x : bricks) { |
| 195 | + t.add(x); |
| 196 | + dfs(v + x); |
| 197 | + t.remove(t.size() - 1); |
| 198 | + } |
| 199 | + } |
| 200 | +} |
| 201 | +``` |
| 202 | + |
| 203 | +### **C++** |
| 204 | + |
| 205 | +```cpp |
| 206 | +class Solution { |
| 207 | +public: |
| 208 | + vector<int> bricks; |
| 209 | + int width; |
| 210 | + int mod = 1e9 + 7; |
| 211 | + vector<vector<int>> res; |
| 212 | + vector<int> t; |
| 213 | + |
| 214 | + int buildWall(int height, int width, vector<int>& bricks) { |
| 215 | + this->width = width; |
| 216 | + this->bricks = bricks; |
| 217 | + dfs(0); |
| 218 | + t.resize(0); |
| 219 | + int n = res.size(); |
| 220 | + vector<vector<int>> g(n); |
| 221 | + for (int i = 0; i < n; ++i) { |
| 222 | + if (check(res[i], res[i])) { |
| 223 | + g[i].push_back(i); |
| 224 | + } |
| 225 | + for (int j = i + 1; j < n; ++j) { |
| 226 | + if (check(res[i], res[j])) { |
| 227 | + g[i].push_back(j); |
| 228 | + g[j].push_back(i); |
| 229 | + } |
| 230 | + } |
| 231 | + } |
| 232 | + vector<vector<int>> dp(height, vector<int>(n)); |
| 233 | + for (int j = 0; j < n; ++j) dp[0][j] = 1; |
| 234 | + for (int i = 1; i < height; ++i) { |
| 235 | + for (int j = 0; j < n; ++j) { |
| 236 | + for (int k : g[j]) { |
| 237 | + dp[i][j] += dp[i - 1][k]; |
| 238 | + dp[i][j] %= mod; |
| 239 | + } |
| 240 | + } |
| 241 | + } |
| 242 | + int ans = 0; |
| 243 | + for (int j = 0; j < n; ++j) { |
| 244 | + ans += dp[height - 1][j]; |
| 245 | + ans %= mod; |
| 246 | + } |
| 247 | + return ans; |
| 248 | + } |
| 249 | + |
| 250 | + bool check(vector<int>& a, vector<int>& b) { |
| 251 | + int s1 = a[0], s2 = b[0]; |
| 252 | + int i = 1, j = 1; |
| 253 | + while (i < a.size() && j < b.size()) { |
| 254 | + if (s1 == s2) return false; |
| 255 | + if (s1 < s2) s1 += a[i++]; |
| 256 | + else s2 += b[j++]; |
| 257 | + } |
| 258 | + return true; |
| 259 | + } |
| 260 | + |
| 261 | + void dfs(int v) { |
| 262 | + if (v > width) return; |
| 263 | + if (v == width) { |
| 264 | + res.push_back(t); |
| 265 | + return; |
| 266 | + } |
| 267 | + for (int x : bricks) { |
| 268 | + t.push_back(x); |
| 269 | + dfs(v + x); |
| 270 | + t.pop_back(); |
| 271 | + } |
| 272 | + } |
| 273 | +}; |
| 274 | +``` |
| 275 | + |
| 276 | +### **Go** |
64 | 277 |
|
| 278 | +```go |
| 279 | +func buildWall(height int, width int, bricks []int) int { |
| 280 | + mod := int(1e9) + 7 |
| 281 | + res := [][]int{} |
| 282 | + t := []int{} |
| 283 | + var dfs func(v int) |
| 284 | + dfs = func(v int) { |
| 285 | + if v > width { |
| 286 | + return |
| 287 | + } |
| 288 | + if v == width { |
| 289 | + cp := make([]int, len(t)) |
| 290 | + copy(cp, t) |
| 291 | + res = append(res, cp) |
| 292 | + return |
| 293 | + } |
| 294 | + for _, x := range bricks { |
| 295 | + t = append(t, x) |
| 296 | + dfs(v + x) |
| 297 | + t = t[:len(t)-1] |
| 298 | + } |
| 299 | + } |
| 300 | + check := func(a, b []int) bool { |
| 301 | + s1, s2 := a[0], b[0] |
| 302 | + i, j := 1, 1 |
| 303 | + for i < len(a) && j < len(b) { |
| 304 | + if s1 == s2 { |
| 305 | + return false |
| 306 | + } |
| 307 | + if s1 < s2 { |
| 308 | + s1 += a[i] |
| 309 | + i++ |
| 310 | + } else { |
| 311 | + s2 += b[j] |
| 312 | + j++ |
| 313 | + } |
| 314 | + } |
| 315 | + return true |
| 316 | + } |
| 317 | + dfs(0) |
| 318 | + n := len(res) |
| 319 | + g := make([][]int, n) |
| 320 | + for i := 0; i < n; i++ { |
| 321 | + if check(res[i], res[i]) { |
| 322 | + g[i] = append(g[i], i) |
| 323 | + } |
| 324 | + for j := i + 1; j < n; j++ { |
| 325 | + if check(res[i], res[j]) { |
| 326 | + g[i] = append(g[i], j) |
| 327 | + g[j] = append(g[j], i) |
| 328 | + } |
| 329 | + } |
| 330 | + } |
| 331 | + dp := make([][]int, height) |
| 332 | + for i := range dp { |
| 333 | + dp[i] = make([]int, n) |
| 334 | + } |
| 335 | + for j := 0; j < n; j++ { |
| 336 | + dp[0][j] = 1 |
| 337 | + } |
| 338 | + for i := 1; i < height; i++ { |
| 339 | + for j := 0; j < n; j++ { |
| 340 | + for _, k := range g[j] { |
| 341 | + dp[i][j] += dp[i-1][k] |
| 342 | + dp[i][j] %= mod |
| 343 | + } |
| 344 | + } |
| 345 | + } |
| 346 | + ans := 0 |
| 347 | + for j := 0; j < n; j++ { |
| 348 | + ans += dp[height-1][j] |
| 349 | + ans %= mod |
| 350 | + } |
| 351 | + return ans |
| 352 | +} |
65 | 353 | ```
|
66 | 354 |
|
67 | 355 | ### **TypeScript**
|
|
0 commit comments