Skip to content

Commit ef4e652

Browse files
committed
feat: add solutions to lc problem: No.2184
No.2184.Number of Ways to Build Sturdy Brick Wall
1 parent 8c67f34 commit ef4e652

File tree

6 files changed

+832
-0
lines changed

6 files changed

+832
-0
lines changed

solution/2100-2199/2184.Number of Ways to Build Sturdy Brick Wall/README.md

+288
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,310 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

49+
**方法一:DFS + 动态规划**
50+
51+
首先通过 DFS 构造出所有合法的排列。然后所有排列进行两两比较,找出每种排列相邻的合法排列,记录在 `g` 数组中。
52+
53+
然后进行动态规划。
54+
55+
过程是这样的:计算以某种排列结束的所有方案数。
56+
57+
初始化第一排每种排列的方案数为 1;每一排选取某种排列的总方案数为上一排能与自己相邻的排列的方案数之和。
58+
59+
答案为最后一排的方案数之和。
60+
4961
<!-- tabs:start -->
5062

5163
### **Python3**
5264

5365
<!-- 这里可写当前语言的特殊实现逻辑 -->
5466

5567
```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
5694

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
57117
```
58118

59119
### **Java**
60120

61121
<!-- 这里可写当前语言的特殊实现逻辑 -->
62122

63123
```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**
64277

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+
}
65353
```
66354

67355
### **TypeScript**

0 commit comments

Comments
 (0)