1473. 给房子涂色 III

思路

根据Hard必死定律,再加上周赛dp必死定律。这道题依旧是没有做出来。但是这次做完了阅读理解,也尝试着在纸上构造了一下转态转移,也算是小有进步吧。

阅读大佬解法,获得新思路:

1.当前房子有颜色
    1.dp[k][i][j] = dp[k-1][i][j] 颜色相同街区不加且当前房子有颜色费用为0
    2.dp[k][i][j+1] = dp[k-1][!=i][j] 颜色不同街区加1当前房子有颜色不用刷当前费用为0
2.当前房子没有颜色
    1.dp[k][i][j] = dp[k-1][i][j] + cost[k][i] 颜色相同街区不加加上刷当前的房子的费用
    2.dp[k][i][j+1] = dp[k-1][!=i][j] + cost[k][i]颜色不同街区加1加上刷当前的房子的费用

以上,尝试写一下代码。

代码

python3

class Solution:
  def minCost(self, houses: List[int], cost: List[List[int]], m: int, n: int, target: int) -> int:
    dp = [[[math.inf for _ in range(m+1)] for _ in range(n+1)] for _ in range(m)]
    if houses[0] != 0:
      dp[0][houses[0]][1] = 0
    else:
      for i in range(1,n+1):
        dp[0][i][1] = cost[0][i-1]
    for k in range(1, m):
      for pc in range(1,n+1): #前一个房间的颜色
        for j in range(1,m):
          if dp[k-1][pc][j] == math.inf: #已经无效,无法进行状态转移
            continue
          if houses[k] != 0: #当前房子已经涂过颜色
            if houses[k] == pc: #当前房子和前一个颜色相同,分组不加
              dp[k][houses[k]][j] = min(dp[k][houses[k]][j], dp[k-1][pc][j])
            else: #不同颜色分组加1
              dp[k][houses[k]][j+1] = min(dp[k][houses[k]][j+1], dp[k-1][pc][j])
          else:
            for c in range(1,n+1): #当前房子未涂过颜色,可以涂任意的颜色
              if c == pc: #当前颜色,不等于前一个颜色,分组不加
                dp[k][c][j] = min(dp[k][c][j], dp[k-1][pc][j] + cost[k][c-1])
              else: #不同颜色,分组加1
                dp[k][c][j+1] = min(dp[k][c][j+1], dp[k-1][pc][j] + cost[k][c-1])
    r = math.inf
    for i in range(1, n+1):
      r = min(r, dp[m-1][i][target])
    return -1 if r == math.inf else r