leetcode 1473. 粉刷房子 III(dp)

在一个小城市里,有 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 个街区。

解题思路

数组dp[i][j][k]中存储的元素含义是前i座房子并且第i座房子的颜色是j并且街区数目为k时,产生的最小花费

代码解读

1.这段代码作用是将房子的颜色从0开始编号,使得后面颜色的遍历直接从0开始

        for (int i = 0; i < houses.length; i++) {houses[i]--;}

2.这段代码作用是初始化dp数组,将全部元素置为最大值,因为题目需要选出的时最小值,因此没有填入元素的位置即为最大值,后面在比较的时候就会失效

        for (int i = 0; i <m ; i++) {for(int j=0;j<n;j++)Arrays.fill(dp[i][j],max);}

3.状态转移

        for (int i = 0; i <m ; i++) {//遍历所有房子for(int j=0;j<n;j++){//遍历所有颜色if(houses[i]!=-1&&houses[i]!=j)  continue;
//条件等价于houses[i]==-1||houses[i]==j,就直接下一轮循环
//houses[i]==-1代表房子没上色,houses[i]==j代表当前房子已经上色并且颜色是j,因为颜色已经固定了,所以
//dp[i][j][k]只能在j==houses[i]的情况下填入元素,颜色j等于其他值的情况是不可能出现for (int k = 0; k < target; k++) {//遍历街区个数for (int p = 0; p < n; p++) {//遍历前一个房子的颜色//先分为两种情况 //情况一:前一个房子和当前房子同色//情况二:前一个房子和当前房子不同色   if (p==j)//情况一:前一个房子和当前房子同色{if(i==0)//1.当前房子是第一家,因此不能从前一座房子转移状态{if(k==0)//当前街区数只可能为0,因为当前只有一家房子,不可能产生k>0 dp[i][j][k]=0;}else{//2.当前房子不是第一家dp[i][j][k]= Math.min(dp[i][j][k],dp[i-1][j][k]);//因为前一个房子和当前房子同色,因此街区数是没有增加的,颜色也是和前面房子的一样}}else if(i>0&&k>0){//情况二:前一个房子和当前房子不同色dp[i][j][k]= Math.min(dp[i][j][k],dp[i-1][p][k-1]);//因为当前房子和前一个房子,颜色不一样,因此需要产生一个新的街区}}if(houses[i]==-1&&dp[i][j][k]!=max)
//houses[i]==-1代表房子没上色,dp[i][j][k]!=max 代表从前面的循环中是不能向dp[i][j][k]填入元素的
//例如 dp[0][j][k](k>1) 这种情况是不可能出现的,因此不能填入元素,也不能在计算这种情况的花费dp[i][j][k]+=cost[i][j];}}}

4.dp[m-1][i][target-1],m-1代表所有房子(前m座房子),target-1代表有target个街区,i是最后一个房子的颜色,找出最小值。

        for (int i = 0; i < n; i++) {res= Math.min(res,dp[m-1][i][target-1]);}

代码

class Solution {static int max=Integer.MAX_VALUE/2;public int minCost(int[] houses, int[][] cost, int m, int n, int target) {int[][][] dp=new int[m][n][target];for (int i = 0; i < houses.length; i++) {houses[i]--;}for (int i = 0; i <m ; i++) {for(int j=0;j<n;j++)Arrays.fill(dp[i][j],max);}for (int i = 0; i <m ; i++) {for(int j=0;j<n;j++){if(houses[i]!=-1&&houses[i]!=j)  continue;for (int k = 0; k < target; k++) {for (int p = 0; p < n; p++) {if (p==j){if(i==0){if(k==0)   dp[i][j][k]=0;}else{dp[i][j][k]= Math.min(dp[i][j][k],dp[i-1][j][k]);}}else if(i>0&&k>0){dp[i][j][k]= Math.min(dp[i][j][k],dp[i-1][p][k-1]);}}if(houses[i]==-1&&dp[i][j][k]!=max)dp[i][j][k]+=cost[i][j];}}}int res=max;for (int i = 0; i < n; i++) {res= Math.min(res,dp[m-1][i][target-1]);}return res==max?-1:res;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大学生信息安全_给大学生的信息

大学生信息安全You’re an undergraduate. Either you’re graduating soon (like me) or you’re in the process of getting your first college degree. The process is not easy and I can only assume how difficult the pressures on Masters and Ph.D. students are. Ho…

打破冷漠僵局文章_保持冷静并打破僵局-最佳

打破冷漠僵局文章Hack The Box (HTB) is an online platform allowing you to test your penetration testing skills. It contains several challenges that are constantly updated. Some of them simulating real world scenarios and some of them leaning more towards a …

使用DOM Breakpoints找到修改属性的Javascript代码

使用Chrome开发者工具的DOM断点功能可以让您快速找到修改了某一个DOM元素的Javascript代码。 在Chrome开发者工具里&#xff0c;选中想要监控的DOM元素&#xff0c;点击右键&#xff0c;选择Break on->Attributes modifications: 之后在DOM Breakpoints的tab里能看到对应的断…

特斯拉最安全的车_特斯拉现在是最受欢迎的租车选择

特斯拉最安全的车Have you been curious to know which cars are most popular in US and what are their typical rental fares in various cities? As the head of Product and Data Science at an emerging technology start-up, Ving Rides, these were some of the quest…

leetcode 740. 删除并获得点数(dp)

给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。 每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除每个等于 nums[i] - 1 或 nums[i] 1 的元素。 开始你拥有 0 个点数。返回你能通过这些操作…

WebSocket入门

WebSocket前言  WebSocket是HTML5的重要特性&#xff0c;它实现了基于浏览器的远程socket&#xff0c;它使浏览器和服务器可以进行全双工通信&#xff0c;许多浏览器&#xff08;Firefox、Google Chrome和Safari&#xff09;都已对此做了支持。 在WebSocket出现之前&#xff…

安卓游戏开发推箱子_保持冷静并砍箱子-开发

安卓游戏开发推箱子Hack The Box (HTB) is an online platform allowing you to test your penetration testing skills. It contains several challenges that are constantly updated. Some of them simulating real world scenarios and some of them leaning more towards …

自定义TabLayout

本文为kotlin仿开眼视频Android客户端的后续补充内容&#xff0c;本篇为大家介绍如何对TabLayout进行定制使用&#xff0c;基于项目需求&#xff0c;本篇主要对部分功能进行了定制&#xff0c;如&#xff1a;指示器距离文字的距离、文字选中加粗、文字选中变大等 本文部分代码参…

ml dl el学习_DeepChem —在生命科学和化学信息学中使用ML和DL的框架

ml dl el学习Application of Machine Learning and Deep Learning for Drug Discovery, Genomics, Microsocopy and Quantum Chemistry can create radical impact and holds the potential to significantly accelerate the process of medical research and vaccine developm…

响应式网站设计_通过这个免费的四小时课程,掌握响应式网站设计

响应式网站设计This video tutorial from Kevin Powell teaches you to build responsive websites from scratch. 凯文鲍威尔(Kevin Powell)的这段视频教程教您从头开始构建响应式网站。 The course starts with explaining the core concepts needed to start thinking resp…

2017-2018-1 20179215《Linux内核原理与分析》第二周作业

20179215《Linux内核原理与分析》第二周作业 这一周主要了解了计算机是如何工作的&#xff0c;包括现在存储程序计算机的工作模型、X86汇编指令包括几种内存地址的寻址方式和push、pop、call、re等几个重要的汇编指令。主要分为两部分进行这周的学习总结。第一部分对学习内容进…

python:单例模式--使用__new__(cls)实现

单例模式&#xff1a;即一个类有且仅有一个实例。 那么通过python怎么实现一个类只能有一个实例呢。 class Earth:"""假如你是神&#xff0c;你可以创造地球"""print 欢迎来到地球# 生成一个地球 a Earth() print id(a)# 再生成一个地球 b Ear…

重学TCP协议(5) 自连接

1.自连接是什么 在发起连接时&#xff0c;TCP/IP的协议栈会先选择source IP和source port&#xff0c;在没有显示调用bind()的情况下&#xff0c;source IP由路由表确定&#xff0c;source port由TCP/IP协议栈从local port range中选取尚未使用的port。 如果destination IP正…

Gradle复制文件/目录方法

2019独角兽企业重金招聘Python工程师标准>>> gradle复制文件/文件夹方法 复制文件 //复制IDE生成的classes.jar文件到build/libs中&#xff0c;并改名为FileUtils.jar. task copyFile(type:Copy) {delete build/libs/FileUtils.jarfrom(build/intermediates/bundles…

用户参与度与活跃度的区别_用户参与度突然下降

用户参与度与活跃度的区别disclaimer: I don’t work for Yammer, this is a public data case study, I’ve written it in a narrative format to make this case study more engaging to read.免责声明&#xff1a;我不为Yammer工作&#xff0c;这是一个公共数据案例研究&am…

python:__new__()与__init__()

参考&#xff1a;https://blog.csdn.net/qq_41020281/article/details/79638370 转载于:https://www.cnblogs.com/gcgc/p/11585599.html

重学TCP协议(6) 四次挥手

1. 四次挥手 客户端进程发出连接释放报文&#xff0c;并且停止发送数据。释放数据报文首部&#xff0c;FIN1&#xff0c;其序列号为sequ&#xff08;等于前面已经传送过来的数据的最后一个字节的序号加1&#xff09;&#xff0c;此时&#xff0c;客户端进入FIN-WAIT-1&#xff…

mysql数据库部分操作指令

用cmd开启服务时拒绝访问. 原因:不是管理员用户&#xff0c;没有权限 将服务中的 MySQL设置为手动启动&#xff0c; 否则 开机自动启动. 启动mysql服务&#xff0c;用管理员权限打开dos界面 windowsX A 打开开始界面 点击管理员开启cmd 启动服务&#xff1a;net start …

推箱子2-向右推!_保持冷静并砍箱子-哔

推箱子2-向右推!Hack The Box (HTB) is an online platform allowing you to test your penetration testing skills. It contains several challenges that are constantly updated. Some of them simulating real world scenarios and some of them leaning more towards a C…

UML建模图实战笔记

一、前言 UML&#xff1a;Unified Modeling Language&#xff08;统一建模语言&#xff09;&#xff0c;使用UML进行建模的作用有哪些&#xff1a; 可以更好的理解问题可以及早的发现错误或者被遗漏的点可以更加方便的进行组员之间的沟通支持面向对象软件开发建模&#xff0c;可…