【C++动态规划】1473. 粉刷房子 III|2056

news/2025/2/4 20:37:01/

本文涉及知识点

C++动态规划

LeetCode1473. 粉刷房子 III

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

动态规划

动态规划的状态表示

dp[i][t][j] 表示 house[0…i-1]都已经涂色,且house[i-1]的颜色是j,目前有t个街区。空间复杂度:O(mnm)
##动态规划的填表顺序
i = 0 to m-1 枚举前置状态

动态规划的转移方程

如果是house[i]已经涂色 j1 = house[i],MinSelf(dp[i+1][t+(j != j1)][j1] ,dp[i][t][j])
如果house[i]没有涂色,枚举j1。MinSelf(dp[i+1][t+(j != j1)][j1] ,dp[i][t][j]+house[i]涂色j1的费用)
单个状态的转移时间复杂度:O(n) 总时间复杂度:O(mmnn)
枚举后序状态,结合前缀最小值和后缀最小值,可以将单个状态时间复杂度降到O(1)。

动态规划的初始值

dp[0][0][0]= 0 其它全部为INT_MAX/2

动态规划的返回值

dp[i][target]的最小值

代码

核心代码

class Solution {public:int minCost(vector<int>& houses, vector<vector<int>>& cost, int m, int n, int target) {vector<vector<vector<int>>> dp(m + 1, vector<vector<int>>(target + 1, vector<int>(n+1,INT_MAX/2)));dp[0][0][0] = 0;for (int i = 0; i < m; i++) {					for (int t = 0; t <= target;t++) {for (int j = 0; j <= n; j++) {auto Add = [&](int j1,int iCost){const int t1 = t + (j1 != j);if (t1 > target)return;dp[i + 1][t1][j1] = min(dp[i + 1][t1][j1], dp[i][t][j] + iCost);};if (0 != houses[i]) {Add(houses[i], 0);}else {for (int j1 = 1; j1 <= n; j1++) {Add(j1, cost[i][j1-1]);}}}}}const int ans = *min_element(dp.back().back().begin(), dp.back().back().end());return ans >= INT_MAX / 2 ? -1 : ans;}};

单元测试

	vector<int> houses;vector<vector<int>> cost;int m,n,target;TEST_METHOD(TestMethod11){houses = { 0,0,0,0,0 }, cost = { {1,10},{10,1},{10,1},{1,10},{5,1} }, m = 5, n = 2, target = 3;auto res = Solution().minCost(houses, cost, m, n, target);AssertEx(9, res);}TEST_METHOD(TestMethod12){houses = { 0,2,1,2,0 }, cost = { {1,10},{10,1},{10,1},{1,10},{5,1} }, m = 5, n = 2, target = 3;auto res = Solution().minCost(houses, cost, m, n, target);AssertEx(11, res);}TEST_METHOD(TestMethod13){houses = { 0,0,0,0,0 }, cost = { {1,10},{10,1},{1,10},{10,1},{1,10} }, m = 5, n = 2, target = 5;auto res = Solution().minCost(houses, cost, m, n, target);AssertEx(5, res);}TEST_METHOD(TestMethod14){houses = { 3,1,2,3 }, cost = { {1,1,1},{1,1,1},{1,1,1},{1,1,1} }, m = 4, n = 3, target = 3;auto res = Solution().minCost(houses, cost, m, n, target);AssertEx(-1, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。


http://www.ppmy.cn/news/1569322.html

相关文章

[EAI-028] Diffusion-VLA,能够进行多模态推理和机器人动作预测的VLA模型

Paper Card 论文标题&#xff1a;Diffusion-VLA: Scaling Robot Foundation Models via Unified Diffusion and Autoregression 论文作者&#xff1a;Junjie Wen, Minjie Zhu, Yichen Zhu, Zhibin Tang, Jinming Li, Zhongyi Zhou, Chengmeng Li, Xiaoyu Liu, Yaxin Peng, Chao…

1. 【.NET Aspire 从入门到实战】--理论入门与环境搭建--引言

在当前软件开发领域&#xff0c;云原生和微服务架构已经成为主流趋势&#xff0c;传统的单体应用正逐步向分布式系统转型。随着业务需求的不断变化与用户规模的迅速扩大&#xff0c;如何在保证高可用、高扩展性的同时&#xff0c;还能提高开发效率与降低维护成本&#xff0c;成…

【C++】线程池实现

目录 一、线程池简介线程池的核心组件实现步骤 二、C11实现线程池源码 三、线程池源码解析1. 成员变量2. 构造函数2.1 线程初始化2.2 工作线程逻辑 3. 任务提交(enqueue方法)3.1 方法签名3.2 任务封装3.3 任务入队 4. 析构函数4.1 停机控制 5. 关键技术点解析5.1 完美转发实现5…

使用MATLAB进行雷达数据采集可视化

本文使用轮趣科技N10雷达&#xff0c;需要源码可在后台私信或者资源自取 1. 项目概述 本项目旨在通过 MATLAB 读取 N10 激光雷达 的数据&#xff0c;并进行 实时 3D 点云可视化。数据通过 串口 传输&#xff0c;并经过解析后转换为 三维坐标点&#xff0c;最终使用 pcplayer 进…

springboot启动配置文件-bootstrap.yml常用基本配置

在Spring Boot应用程序中&#xff0c;bootstrap.yml文件通常用于配置应用程序的启动阶段。在这个文件中&#xff0c;你可以配置一些在应用程序启动之前需要加载的属性&#xff0c;例如外部配置源、加密属性等。以下是一些常用的基本配置项&#xff1a; 1. 外部配置源 1.1 配置…

因果推断与机器学习—因果推断入门(1)

在机器学习被广泛应用于对人类产生巨大影响的场景(如社交网络、电商、搜索引擎等)的今天,因果推断的重要性开始在机器学习社区的论文和演讲中被不断提及。图灵奖得主 Yoshua Bengio 在对系统 2(system 2,这个说法来自心理学家 Daniel Kahneman 的作品,人类大脑由两套系统…

Spring Boot 热部署实现指南

在开发 Spring Bot 项目时&#xff0c;热部署功能能够显著提升开发效率&#xff0c;让开发者无需频繁重启服务器就能看到代码修改后的效果。下面为大家详细介绍一种实现 Spring Boot 热部署的方法&#xff0c;同时也欢迎大家补充其他实现形式。 步骤一、开启 IDEA 自动编译功能…

联想Y7000+RTX4060+i7+Ubuntu22.04运行DeepSeek开源多模态大模型Janus-Pro-1B+本地部署

直接上手搓了&#xff1a; conda create -n myenv python3.10 -ygit clone https://github.com/deepseek-ai/Janus.gitcd Januspip install -e .pip install webencodings beautifulsoup4 tinycss2pip install -e .[gradio]pip install pexpect>4.3python demo/app_januspr…