Skip to content

Commit 80263e0

Browse files
committed
feat: add solutions to lc problem: No.1473
No.1473.Paint House III
1 parent cd3aa19 commit 80263e0

File tree

6 files changed

+594
-1
lines changed

6 files changed

+594
-1
lines changed

Diff for: solution/1400-1499/1473.Paint House III/README.md

+216-1
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,237 @@
7474

7575
<!-- 这里可写通用的实现逻辑 -->
7676

77+
**方法一:动态规划**
78+
79+
我们定义 $f[i][j][k]$ 表示将下标 $[0,..i]$ 的房子涂上颜色,最后一个房子的颜色为 $j$,且恰好形成 $k$ 个街区的最小花费。那么答案就是 $f[m-1][j][target]$,其中 $j$ 的取值范围为 $[1,..n]$。初始时,我们判断下标为 $0$ 的房子是否已经涂色,如果未涂色,那么 $f[0][j][1] = cost[0][j - 1]$,其中 $j \in [1,..n]$。如果已经涂色,那么 $f[0][houses[0]][1] = 0$。其他的 $f[i][j][k]$ 的值都初始化为 $\infty$。
80+
81+
接下来,我们从下标 $i=1$ 开始遍历,对于每个 $i$,我们判断下标为 $i$ 的房子是否已经涂色:
82+
83+
如果未涂色,那么我们可以将下标为 $i$ 的房子涂成颜色 $j$,我们枚举街区的数量 $k$,其中 $k \in [1,..min(target, i + 1)]$,并且枚举下标为 $i$ 的房子的前一个房子的颜色 $j_0$,其中 $j_0 \in [1,..n]$,那么我们可以得到状态转移方程:
84+
85+
$$
86+
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] + cost[i][j - 1] \}
87+
$$
88+
89+
如果已经涂色,那么我们可以将下标为 $i$ 的房子涂成颜色 $j$,我们枚举街区的数量 $k$,其中 $k \in [1,..min(target, i + 1)]$,并且枚举下标为 $i$ 的房子的前一个房子的颜色 $j_0$,其中 $j_0 \in [1,..n]$,那么我们可以得到状态转移方程:
90+
91+
$$
92+
f[i][j][k] = \min_{j_0 \in [1,..n]} \{ f[i - 1][j_0][k - (j \neq j_0)] \}
93+
$$
94+
95+
最后,我们返回 $f[m - 1][j][target]$,其中 $j \in [1,..n]$,如果所有的 $f[m - 1][j][target]$ 的值都为 $\infty$,那么返回 $-1$。
96+
97+
时间复杂度 $O(m \times n^2 \times target)$,空间复杂度 $O(m \times n \times target)$。其中 $m$, $n$, $target$ 分别为房子的数量,颜色的数量,街区的数量。
98+
7799
<!-- tabs:start -->
78100

79101
### **Python3**
80102

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

83105
```python
84-
106+
class Solution:
107+
def minCost(self, houses: List[int], cost: List[List[int]], m: int, n: int, target: int) -> int:
108+
f = [[[inf] * (target + 1) for _ in range(n + 1)] for _ in range(m)]
109+
if houses[0] == 0:
110+
for j, c in enumerate(cost[0], 1):
111+
f[0][j][1] = c
112+
else:
113+
f[0][houses[0]][1] = 0
114+
for i in range(1, m):
115+
if houses[i] == 0:
116+
for j in range(1, n + 1):
117+
for k in range(1, min(target + 1, i + 2)):
118+
for j0 in range(1, n + 1):
119+
if j == j0:
120+
f[i][j][k] = min(
121+
f[i][j][k], f[i - 1][j][k] + cost[i][j - 1])
122+
else:
123+
f[i][j][k] = min(
124+
f[i][j][k], f[i - 1][j0][k - 1] + cost[i][j - 1])
125+
else:
126+
j = houses[i]
127+
for k in range(1, min(target + 1, i + 2)):
128+
for j0 in range(1, n + 1):
129+
if j == j0:
130+
f[i][j][k] = min(f[i][j][k], f[i - 1][j][k])
131+
else:
132+
f[i][j][k] = min(f[i][j][k], f[i - 1][j0][k - 1])
133+
134+
ans = min(f[-1][j][target] for j in range(1, n + 1))
135+
return -1 if ans >= inf else ans
85136
```
86137

87138
### **Java**
88139

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

91142
```java
143+
class Solution {
144+
public int minCost(int[] houses, int[][] cost, int m, int n, int target) {
145+
int[][][] f = new int[m][n + 1][target + 1];
146+
final int inf = 1 << 30;
147+
for (int[][] g : f) {
148+
for (int[] e : g) {
149+
Arrays.fill(e, inf);
150+
}
151+
}
152+
if (houses[0] == 0) {
153+
for (int j = 1; j <= n; ++j) {
154+
f[0][j][1] = cost[0][j - 1];
155+
}
156+
} else {
157+
f[0][houses[0]][1] = 0;
158+
}
159+
for (int i = 1; i < m; ++i) {
160+
if (houses[i] == 0) {
161+
for (int j = 1; j <= n; ++j) {
162+
for (int k = 1; k <= Math.min(target, i + 1); ++k) {
163+
for (int j0 = 1; j0 <= n; ++j0) {
164+
if (j == j0) {
165+
f[i][j][k] = Math.min(f[i][j][k], f[i - 1][j][k] + cost[i][j - 1]);
166+
} else {
167+
f[i][j][k] = Math.min(f[i][j][k], f[i - 1][j0][k - 1] + cost[i][j - 1]);
168+
}
169+
}
170+
}
171+
}
172+
} else {
173+
int j = houses[i];
174+
for (int k = 1; k <= Math.min(target, i + 1); ++k) {
175+
for (int j0 = 1; j0 <= n; ++j0) {
176+
if (j == j0) {
177+
f[i][j][k] = Math.min(f[i][j][k], f[i - 1][j][k]);
178+
} else {
179+
f[i][j][k] = Math.min(f[i][j][k], f[i - 1][j0][k - 1]);
180+
}
181+
}
182+
}
183+
}
184+
}
185+
int ans = inf;
186+
for (int j = 1; j <= n; ++j) {
187+
ans = Math.min(ans, f[m - 1][j][target]);
188+
}
189+
return ans >= inf ? -1 : ans;
190+
}
191+
}
192+
```
193+
194+
### **C++**
195+
196+
```cpp
197+
class Solution {
198+
public:
199+
int minCost(vector<int>& houses, vector<vector<int>>& cost, int m, int n, int target) {
200+
int f[m][n + 1][target + 1];
201+
memset(f, 0x3f, sizeof(f));
202+
if (houses[0] == 0) {
203+
for (int j = 1; j <= n; ++j) {
204+
f[0][j][1] = cost[0][j - 1];
205+
}
206+
} else {
207+
f[0][houses[0]][1] = 0;
208+
}
209+
for (int i = 1; i < m; ++i) {
210+
if (houses[i] == 0) {
211+
for (int j = 1; j <= n; ++j) {
212+
for (int k = 1; k <= min(target, i + 1); ++k) {
213+
for (int j0 = 1; j0 <= n; ++j0) {
214+
if (j == j0) {
215+
f[i][j][k] = min(f[i][j][k], f[i - 1][j][k] + cost[i][j - 1]);
216+
} else {
217+
f[i][j][k] = min(f[i][j][k], f[i - 1][j0][k - 1] + cost[i][j - 1]);
218+
}
219+
}
220+
}
221+
}
222+
} else {
223+
int j = houses[i];
224+
for (int k = 1; k <= min(target, i + 1); ++k) {
225+
for (int j0 = 1; j0 <= n; ++j0) {
226+
if (j == j0) {
227+
f[i][j][k] = min(f[i][j][k], f[i - 1][j][k]);
228+
} else {
229+
f[i][j][k] = min(f[i][j][k], f[i - 1][j0][k - 1]);
230+
}
231+
}
232+
}
233+
}
234+
}
235+
int ans = 0x3f3f3f3f;
236+
for (int j = 1; j <= n; ++j) {
237+
ans = min(ans, f[m - 1][j][target]);
238+
}
239+
return ans == 0x3f3f3f3f ? -1 : ans;
240+
}
241+
};
242+
```
92243
244+
### **Go**
245+
246+
```go
247+
func minCost(houses []int, cost [][]int, m int, n int, target int) int {
248+
f := make([][][]int, m)
249+
const inf = 1 << 30
250+
for i := range f {
251+
f[i] = make([][]int, n+1)
252+
for j := range f[i] {
253+
f[i][j] = make([]int, target+1)
254+
for k := range f[i][j] {
255+
f[i][j][k] = inf
256+
}
257+
}
258+
}
259+
if houses[0] == 0 {
260+
for j := 1; j <= n; j++ {
261+
f[0][j][1] = cost[0][j-1]
262+
}
263+
} else {
264+
f[0][houses[0]][1] = 0
265+
}
266+
for i := 1; i < m; i++ {
267+
if houses[i] == 0 {
268+
for j := 1; j <= n; j++ {
269+
for k := 1; k <= target && k <= i+1; k++ {
270+
for j0 := 1; j0 <= n; j0++ {
271+
if j == j0 {
272+
f[i][j][k] = min(f[i][j][k], f[i-1][j][k]+cost[i][j-1])
273+
} else {
274+
f[i][j][k] = min(f[i][j][k], f[i-1][j0][k-1]+cost[i][j-1])
275+
}
276+
}
277+
}
278+
}
279+
} else {
280+
j := houses[i]
281+
for k := 1; k <= target && k <= i+1; k++ {
282+
for j0 := 1; j0 <= n; j0++ {
283+
if j == j0 {
284+
f[i][j][k] = min(f[i][j][k], f[i-1][j][k])
285+
} else {
286+
f[i][j][k] = min(f[i][j][k], f[i-1][j0][k-1])
287+
}
288+
}
289+
}
290+
}
291+
}
292+
ans := inf
293+
for j := 1; j <= n; j++ {
294+
ans = min(ans, f[m-1][j][target])
295+
}
296+
if ans == inf {
297+
return -1
298+
}
299+
return ans
300+
}
301+
302+
func min(a, b int) int {
303+
if a < b {
304+
return a
305+
}
306+
return b
307+
}
93308
```
94309

95310
### **...**

0 commit comments

Comments
 (0)