粉刷房子 III
在一个小城市里,有 m
个房子排成一排,你需要给每个房子涂上 n
种颜色之一(颜色编号为 1
到 n
)。有的房子去年夏天已经涂过颜色了,所以这些房子不需要被重新涂色。
我们将连续相同颜色尽可能多的房子称为一个街区。(比方说 houses = [1,2,2,3,3,2,1,1]
,它包含 5 个街区 [{1}, {2,2}, {3,3}, {2}, {1,1}]
。)
给你一个数组 houses
,一个 m * n
的矩阵 cost
和一个整数 target
,其中:
houses[i]
:是第i
个房子的颜色,0 表示这个房子还没有被涂色。cost[i][j]
:是将第i
个房子涂成颜色j+1
的花费。
请你返回房子涂色方案的最小总花费,使得每个房子都被涂色后,恰好组成 target
个街区。如果没有可用的涂色方案,请返回 -1 。
示例 1:
输入:houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3 输出:9 解释:房子涂色方案为 [1,2,2,1,1] 此方案包含 target = 3 个街区,分别是 [{1}, {2,2}, {1,1}]。 涂色的总花费为 (1 + 1 + 1 + 1 + 5) = 9。
示例 2:
输入:houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3 输出:11 解释:有的房子已经被涂色了,在此基础上涂色方案为 [2,2,1,2,2] 此方案包含 target = 3 个街区,分别是 [{2,2}, {1}, {2,2}]。 给第一个和最后一个房子涂色的花费为 (10 + 1) = 11。
示例 3:
输入:houses = [0,0,0,0,0], cost = [[1,10],[10,1],[1,10],[10,1],[1,10]], m = 5, n = 2, target = 5 输出:5
示例 4:
输入:houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], m = 4, n = 3, target = 3 输出:-1 解释:房子已经被涂色并组成了 4 个街区,分别是 [{3},{1},{2},{3}] ,无法形成 target = 3 个街区。
提示:
m == houses.length == cost.length
n == cost[i].length
1 <= m <= 100
1 <= n <= 20
1 <= target <= m
0 <= houses[i] <= n
1 <= cost[i][j] <= 10^4
Related Topics
分析
- 将房区初始颜色编码从0开始计算,-1表示未涂颜色。
- 记
dp[i][j][k]
为第i
个房子涂成颜色j
的花费,它属于第k
个街区 - 我们讨论第
i
个房子花费:若i!=0
,设第i-1
个房子颜色为j0
- 对于
houses[i] = -1
,即房子未涂颜色。分为两种情况:j = j0
:颜色和i-1
一致,i
和i-1
属于同一街区,得如下转移方程:
$$
dp[i][j][k] = dp[i-1][j][k] + const[i][j]
$$j != j0
:颜色变化,i
和i-1
不属于同一街区,得如下转移方程:
$$
dp[i][j][k] = dp[i-1][j0][k-1] + const[i][j]
$$
- 对于
houses[i] != -1
,即房子有初始颜色j,这种情况必须将房子涂成颜色j。同样分为两种情况:j = j0
:颜色和i-1
一致,i
和i-1
属于同一街区,这时不需要额外为i涂色。得如下转移方程:
$$
dp[i][j][k] = dp[i-1][j][k]
$$j != j0
:颜色变化,i
和i-1
不属于同一街区,这时不需要额外为i涂色,得如下转移方程:
$$
dp[i][j][k] = dp[i-1][j0][k-1]
$$
- 对于
- 若
i = 0
,由于第一个房子,所以k = 0
,花费不由上一个房子转移得到。,分为两种情况:houses[i] = -1
,即房子未涂颜色,花费:const[i][j]
houses[i] != -1
,即房子有初始颜色j,j = j0
,花费:0
转化为代码:
1 | public class Solution1473 { |