在一个小城市里,有
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
标签:动态规划
动态规划
题目中有一点说得不太明确,题目中说已经粉刷过的房子不需要再刷,题目本意应该是去年夏天刷过的房子不准再刷,说不需要感觉还是可以再被刷成其他颜色,所以说有一点不太明确。但是两种意思都挺有意思的,而且代码层面差别不大,这里我就把两种情况的个人解答都写出来了。
其实两种题目的动态规划解题思路大致是一样的:
- 首先我们可以看出房子i
的状态只跟房子i-1
的状态有关,状态可以按target
来分,即每个房子可以有target
种状态,每种状态还可以分为n
种颜色,所以这里要用三维DP → d p [ m ] [ t a r g e t ] [ n ] \rightarrow dp[m][target][n] →dp[m][target][n]。
- 确定完状态下面就要推状态转移方程了。假设现在状态为dp[i][j][k]
,即房子i
处于j
街区时颜色为k
的最小cost
。首先按街区分为两种,j = 0
和j > 0
:
→ j = 0 \rightarrow j = 0 →j=0: 说明房子i
还处于第一街区,所以它的颜色必须和前一个房子i-1
相同,所以 d p [ i ] [ j ] [ k ] = d p [ i − 1 ] [ j ] [ k ] + c o s t [ i ] [ k ] dp[i][j][k] = dp[i-1][j][k] + cost[i][k] dp[i][j][k]=dp[i−1][j][k]+cost[i][k]
→ j > 0 \rightarrow j > 0 →j>0: 此时房子已经不属于第一街区了,所以它的上一个房子i-1
可以和i
颜色相同(即i-1
和i
属于同一街区j),也可以不同(即i-1
属于i
的上一个街区j-1
),所以我们只需从所有可能性中选出cost
最小的那一个所以 d p [ i ] [ j ] [ k ] = m i n ( [ d p [ i − 1 ] [ j ] [ k ] ] + [ d p [ i − 1 ] [ j − 1 ] [ c ] f o r c i n r a n g e ( n ) i f c ! = k ] )