题目是LeetCode第192场周赛的第四题,链接:1473. 给房子涂色 III。具体描述为:在一个小城市里,有m个房子排成一排,你需要给每个房子涂上n种颜色之一(颜色编号为1n)。有的房子去年夏天已经涂过颜色了,所以这些房子不需要被重新涂色。我们将连续相同颜色尽可能多的房子称为一个街区。(比方说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 个街区。

 很明显又是一道动态规划的题目,因为我们在染某个房子的时候,如果颜色跟上一个房子的不一样,那街区数就会加1,否则不变,所以在状态数组里面必然是要有颜色这个变量存在的。不妨记dp[i][j][k]0~i的房子被分成j+1个街区且第i个房子染的颜色为k+1的最小总花费。那么我们在求dp[i][j][k]时就有以下情况:

  • i个房子已经涂过颜色(houses[i]!=0),那么很明显,所有的dp[i][j][k](k!=houses[i]-1)都是不存在的(可以设置为一个特定值,比如整型的最大值),那么对于dp[i][j][k](k==houses[i]-1),则根据上一个房子的颜色可以知道到当前房子为止的街区数(相同不增不减,不同加1),遍历上一个房子的颜色,找到最小值即可:dp[i][j][k]=min(dp[i-1][j-1][p!=k],dp[i-1][j][k])
  • i个房子没涂过颜色(houses[i]==0),我们要做的就是给这个房子涂上所有可能的颜色,然后这个过程中同样需要跟上一个房子的颜色相比决定到当前房子为止的街区数,同样找最小值即可:dp[i][j][k]=min(dp[i-1][j][k]+cost[i][k],dp[i-1][j-1][p!=k]+cost[i][p!=k])

 时间复杂度为O(mn2t)O(mn^{2}t)O(mn2t),空间复杂度为O(mnt)O(mnt)O(mnt)。

 JAVA版代码如下:

class Solution {public int minCost(int[] houses, int[][] cost, int m, int n, int target) {// dp[i][j][k]: 0~i这些房子分成了j+1个区,且第i个房子的颜色为k + 1int[][][] dp = new int[m][target][n];for (int i = 0; i < m; ++i) {for (int j = 0; j < target; ++j) {Arrays.fill(dp[i][j], Integer.MAX_VALUE);}}if (houses[0] != 0) {dp[0][0][houses[0] - 1] = 0;}else {for (int k = 0; k < n; ++k) {dp[0][0][k] = cost[0][k];}}for (int i = 1; i < m; ++i) {for (int j = 0; j < target; ++j) {for (int k = 0; k < n; ++k) {// 当前房子如果已经染过色了,花费不增加if (houses[i] != 0 && houses[i] - 1 != k) {continue;}int c = cost[i][k];int color = k;if (houses[i] != 0) {c = 0;color = houses[i] - 1;}// 遍历上一个房子可能的颜色,颜色相同时当前街区数不变,否则需要+1int min = dp[i - 1][j][color];if (j > 0) {for (int p = 0; p < n; ++p) {if (p == color) {continue;}min = Math.min(min, dp[i - 1][j - 1][p]);}}if (min != Integer.MAX_VALUE) {dp[i][j][k] = Math.min(min + c, dp[i][j][k]);}}}}int result = Integer.MAX_VALUE;for (int k = 0; k < n; ++k) {if (dp[m - 1][target - 1][k] != Integer.MAX_VALUE) {result = Math.min(dp[m - 1][target - 1][k], result);}}return result == Integer.MAX_VALUE ? -1 : result;}
}

 提交结果如下:

 Python版代码如下:

class Solution:def minCost(self, houses: List[int], cost: List[List[int]], m: int, n: int, target: int) -> int:MAX_VALUE = 10_000_000dp = [[[MAX_VALUE for _ in range(n)] for _ in range(target)] for _ in range(m)]if houses[0] == 0:for k in range(n):dp[0][0][k] = cost[0][k]else:dp[0][0][houses[0] - 1] = 0for i in range(1, m):for j in range(target):for k in range(n):if houses[i] != 0 and k != houses[i] - 1:continuec = cost[i][k] if houses[i] == 0 else 0color = k if houses[i] == 0 else houses[i] - 1minc = dp[i - 1][j][color]if j > 0:for p in range(n):if p == k:continueminc = min(minc, dp[i - 1][j - 1][p])dp[i][j][k] = min(dp[i][j][k], minc + c)result = min(dp[m - 1][target - 1][:])return -1 if result == MAX_VALUE else result

 提交结果如下:

leetcode--给房子涂色III相关推荐

  1. LeetCode 1473. 给房子涂色 III(DP)

    1. 题目 在一个小城市里,有 m 个房子排成一排,你需要给每个房子涂上 n 种颜色之一(颜色编号为 1 到 n ). 有的房子去年夏天已经涂过颜色了,所以这些房子不需要被重新涂色. 我们将连续相同颜 ...

  2. LeetCode 276. 栅栏涂色(DP)

    文章目录 1. 题目 2. 解题 2.1 DP超时解 2.2 DP解 1. 题目 有 k 种颜色的涂料和一个包含 n 个栅栏柱的栅栏,每个栅栏柱可以用其中一种颜色进行上色. 你需要给所有栅栏柱上色,并 ...

  3. Leetcode 276.栅栏涂色

    Time: 20190904 Type: Easy 考察:动态规划 题目描述 有 k 种颜色的涂料和一个包含 n 个栅栏柱的栅栏,每个栅栏柱可以用其中一种颜色进行上色. 你需要给所有栅栏柱上色,并且保 ...

  4. ​LeetCode刷题实战276:栅栏涂色

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  5. LeetCode 1411. 给 N x 3 网格图涂色的方案数(数学)

    1. 题目 你有一个 n x 3 的网格图 grid ,你需要用 红,黄,绿 三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就是有相同水平边或者垂直边的格子颜色不同). 给你网格图的行数 n ...

  6. leetcode 5383. 给 N x 3 网格图涂色的方案数

    leetcode 5383. 给 N x 3 网格图涂色的方案数 来源:力扣(LeetCode) 你有一个 n x 3 的网格图 grid ,你需要用 红,黄,绿 三种颜色之一给每一个格子上色,且确保 ...

  7. leetcode 给N x 3网络图涂色的方案数

    1.题目详情       leetcode 给N x 3网络图涂色的方案数 你有一个 n x 3 的网格图 grid ,你需要用 红,黄,绿 三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就 ...

  8. 得到 K 个黑块的最少涂色次数

    leetcode 2379. 得到 K 个黑块的最少涂色次数 给你一个长度为 n 下标从 0 开始的字符串 blocks ,blocks[i] 要么是 'W' 要么是 'B' ,表示第 i 块的颜色. ...

  9. OpenCV(一)图像读取与新建、图像显示、操作图像像素(2种涂色并比较算法优劣、输出RGB)

    目录 一.读取图像与新建图像 1.读取图像 2.新建图像 二.显示图像 1.过程 2.代码 3.运行效果 三.操作图像像素 1.逐RGB涂色(单循环)(快) 1-1.过程 2-2.代码 2-3.运行结 ...

最新文章

  1. linux快速上手之多服务器间路由配置
  2. UA MATH567 高维统计I 概率不等式8 亚指数范数
  3. 平衡二叉树平衡因子_数据结构:平衡二叉树
  4. C#委托的定义 以及使用方式详解,更简单的理解委托。
  5. JS:ES6-6 初识Symbol类型
  6. html自动旋转屏幕,求教!HTML5屏幕旋转90度再让画布自适应,该如何做,大神给留demo...
  7. 文件转Base64格式
  8. oppo r11s鸿蒙固件,OPPO R11s官方出厂rom系统刷机包下载_卡刷升级包降级回退包
  9. scipy--统计检验
  10. [ROS] KDL + DH 参数 + 正解
  11. OpenCV开发笔记(六十):红胖子8分钟带你深入了解Harris角点检测(图文并茂+浅显易懂+程序源码)
  12. 防止padding撑开盒子的方法
  13. SpringBoot开发文档二(MD5二次加密)
  14. 国际短信系统平台后台功能详解-移讯云短信软件
  15. RabbitMQ的持久化
  16. 网间进程的标识和端口分配机制
  17. 4月8日云栖精选夜读:阿里巴巴与清华大学成立联合实验室 机器将有五感、懂感情
  18. 关于解析XML文件时遇到的一些错误
  19. 关于Oracle表空间不足问题(ora-01144)
  20. 刘慈欣的宇宙文明点状化模拟

热门文章

  1. 爬虫入门经典(十九) | 难度提升,破解极验验证码
  2. html 设置移动端页面滚动,a.html · 焚心/移动端页面上下滚动加多页面上拉加载功能及mescroll插件的使用 - Gitee.com...
  3. Navicat导出整个数据库(可以直接迁移,不会因为外键关系而导致导入不了)
  4. Python爬虫入门之2022软科中国大学排名爬取保存到csv文件
  5. Unity3d导出的安卓包如何在真机上看log打印
  6. python余弦函数,Python余弦函数精度
  7. v-chart柱状图点击改变颜色
  8. 数据库系统原理学习(三)--PG数据定义与操作
  9. 哔哩哔哩bilibili 直播间全屏发弹幕
  10. 秋招斩获所有互联网大厂面经之算法