详解三维动态规划该如何求解,以及状态定义的由来|Java 刷题打卡

本文正在参加「Java主题月 – Java 刷题打卡」,详情查看 活动链接

题目描述

这是 LeetCode 上的1473. 粉刷房子 III,难度为 Hard

在一个小城市里,有 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] <= 10410^4

动态规划

定义 f[i][j][k]f[i][j][k] 为考虑前 ii 间房子,且第 ii 间房子的颜色编号为 jj,前 ii 间房子形成的分区数量为 kk 的所有方案中的「最小上色成本」。

我们不失一般性的考虑 f[i][j][k]f[i][j][k] 该如何转移,由于某些房子本身就已经上色,上色的房子是不允许被粉刷的。

我们可以根据第 ii 间房子是否已经被上色,进行分情况讨论:

  • ii 间房子已经被上色,即 houses[i]!=0houses[i] != 0,此时只有满足 j==houses[i]j == houses[i] 的状态才是有意义的,其余状态均为 INF

    同时根据「第 ii 间房子的颜色 jj」与「第 i1i – 1 间房子的颜色 pp」是否相同,会决定第 ii 间房子是否形成一个新的分区。这同样需要进行分情况讨论。

    整理后的转移方程为:

f[i][j][k]={min(f[i1][j][k],f[i1][p][k1])j==houses[i],p!=jINFj!=houses[i]f[i][j][k]=\begin{cases} min(f[i – 1][j][k], f[i – 1][p][k – 1]) &j == houses[i], p != j\\ INF & j != houses[i] \end{cases}

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享