动态规划算法:14.简单多状态 dp 问题_粉刷房子_C++

 题目链接:LCR 091. 粉刷房子 - 力扣(LeetCode)

一、题目解析

题目:

解析:

由题可知:

  • 涂刷房子有三种颜色可以选,所给的二维数组中三列固定不变,分别是红、蓝、绿
  • 相邻两件房子不可以涂刷相同的颜色
  • 要求涂刷完成后价格最少

举示例1:

在所有能满足相邻房子颜色不同这个条件的方法中,该方法花费最少,为蓝绿蓝

二、算法原理

1、状态表示

我们在状态表示的时候,一般都会创建一个数组dp,也就是我们所说的dp表,我们要做的就是把每一个状态的值填入这个表内,最终这个表内的某一个值可能就是我们要返回的值。 

  状态简单理解就是dp表内某一个值代表的含义。

如何确定状态表示

  • 题目要求

   简单的题目里一般会给出

  • 经验+题目要求

  越学越深入,动态规划也是熟能生巧,在题目中没有明显给出的时候,我们就要凭借自己做题的经验来确定,所以就需要我们大量的做题。

  • 分析问题的过程中,发现重复子问题

 分析问题的过程中把重复子问题抽象成我们的状态表示,这个更难理解,一切的基础都是我们先对动态规划算法熟练运用。我也不懂,我们慢慢来。

综上:我们通常会以一个位置为结尾或者开始求得我们想要的答案

那我们的这道题得状态表示是什么样的:

根据经验,可得

状态表示:dp[i][j]表示为用j颜色粉刷第i个房子时的最小花费

2、状态转移方程

 确定状态表示之后我们就可以根据状态标识推出状态转移方程

  状态转移方程是什么?

不讲什么复杂的,简单来说状态转移方程就是    dp[i][j]等于什么 dp[i][j]=?

  这个就是状态转移方程,我们要做的,就是推出dp[i][j]等于什么

  我们根据状态表示再结合题目+经验去推理转移方程,这一步也是我们整个解题过程中最难的一步

  状态转移方程推理:

  我们能够知道,我们在粉刷每一个房子时,都有三个不同的选择,可以选择红,也可以选择蓝或者绿,那究竟粉刷哪个颜色,是取决于前一个房子粉刷的颜色

  换个思维,我们在涂刷这个房子时,如果把它涂刷成蓝色,那它前一个房子就只能是红色或者绿色

  我们从第一个房子开始涂刷,所以第一个房子有三种颜色供我们选择,这时候我们创建三个dp表,分别表示,用j颜色涂刷完该房子时所需的最小花费

记录下这三种颜色的状态,我们在涂刷下一个房子时,可以根据上一个房子的三种状态来选择花费较小的颜色

下图便是我们的状态转移方程分析图:

例如:我们想把i位置涂刷成红色,那么我们直接用上一个房子(i-1)的蓝绿状态比较取最小值就可以知道哪种种状态花费最小,再加上涂刷该位置的花费cost[i][0],就是涂刷到该位置时的总最小花费dp[i][0]

状态转移方程:

  • dp[i][0]=min(dp[i-1][1],dp[i-1][2])+costs[i][0];
  • dp[i][1]=min(dp[i-1][0],dp[i-1][2])+costs[i][1];
  • dp[i][2]=min(dp[i-1][1],dp[i-1][0])+costs[i][2];

3、初始化

 我们创建dp表就是为了把他填满,我们初始化是为了防止在填表的过程中越界

怎么谈越界?

例如:我们在填dp[0][0]时,我们会发现,dp[-1][1]和dp[-1][2]不存在

dp表初始化:

为了防止越界,我们将dp表的行大小在初始化时,设置成n+1,n为原数组cost行大小

此时需要注意下表映射,dp[1][0]、dp[1][1]、dp[1][2]才是我们涂刷到第一个房间时的三种颜色的最小花费

特殊位置初始化:

  我们需要对dp[0][0]、dp[0][1]、dp[0][2]三个位置初始化,防止越界,也使得在填后一个位置时,填表正确

  我们将这三个位置初始化为0即可,使得不影响后续填表

  再求dp[1][0]dp[1][1]dp[1][2]时,状态转移方程会加上cost[0][0]、cost[0][1]、cost[0][2]

  

4、填表顺序

从左到右,三个表同时填写

5、返回值

需要将涂刷到最后一个房子时的三种状态作比较,取最小值

三、编写代码

class Solution {
public:int minCost(vector<vector<int>>& costs) {int n=costs.size();
//dp表的创建vector<vector<int>> dp(n+1,vector<int>(3,0));
//填表for(int i=1;i<=n;i++){dp[i][0]=min(dp[i-1][1],dp[i-1][2])+costs[i-1][0];dp[i][1]=min(dp[i-1][0],dp[i-1][2])+costs[i-1][1];dp[i][2]=min(dp[i-1][1],dp[i-1][0])+costs[i-1][2];}
//返回值return min(min(dp[n][0],dp[n][1]),dp[n][2]);}
};

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

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

相关文章

C++基础面试题 | 什么是内存对齐?为什么需要内存对齐?

文章目录 回答重点扩展知识 回答重点 内存对齐是指计算机在访问内存时&#xff0c;会根据一定规则将数据存储在合适的起始地址上&#xff0c;通常是数据大小的整数倍。这样做可以提升CPU的访问效率&#xff0c;特别是在读取和写入数据时。 为什么要内存对齐&#xff1f;主要有…

无极低码课程【mysql windows下安装要点】

在Windows环境中安装MySQL 5.7教程 MySQL 是世界上最流行的开源关系型数据库管理系统之一。本教程将指导您在Windows操作系统上安装MySQL 5.7。 网上教程较多&#xff0c;这里不再详述&#xff0c;注意关键点即可 准备工作 下载MySQL 5.7安装包 访问 MySQL官方网站 下载MyS…

【Java面试——基础知识——Day2】

1.面向对象基础 1.1 面向对象和面向过程的区别 面向过程编程&#xff08;POP&#xff09;&#xff1a;面向过程把解决问题的过程拆成一个个方法&#xff0c;通过一个个方法的执行解决问题。面向对象编程&#xff08;OOP&#xff09;&#xff1a;面向对象会先抽象出对象&#…

并查集---We Are A Team

题目描述 总共有 n 个人在机房&#xff0c;每个人有一个标号&#xff08;1<标号<n&#xff09;&#xff0c;他们分成了多个团队&#xff0c;需要你根据收到的 m 条消息判定指定的两个人是否在一个团队中&#xff0c;具体的&#xff1a; 消息构成为 a b c&#xff0c;整数…

使用React Router实现前端的权限访问控制

前段时间学习了React Router&#xff0c;发现没有Vue里面的路由功能强大&#xff0c;没有直接提供路由中间件&#xff0c;不能像Vue里面一样在路由配置上设置任意的额外属性&#xff0c;但是可以通过一些技巧来实现这些功能。 1、配置菜单 后台管理系统一般都会在左侧显示菜单…

“链动2+1+消费增值:用户留存新策略“

大家好&#xff0c;我是吴军&#xff0c;目前在一家以创新为核心的软件开发公司担任产品经理。今天&#xff0c;我将深入探讨一个经受住了时间考验且依然充满活力的商业模式——“链动21”模式&#xff0c;并通过一个实例及相关数据展示它如何巧妙应对用户留存与复购的挑战。 首…

【JS】在 Node.js 和 Electron 中获取设备 UUID 的最佳实践

在现代应用开发中&#xff0c;识别设备的唯一性是一个常见需求。无论是为了授权、数据跟踪还是用户设备管理&#xff0c;获取设备 UUID 都是实现这些目标的关键。在这篇博客中&#xff0c;我们将探讨如何在 Node.js 和 Electron 中获取设备的 UUID&#xff0c;并比较两种主要方…

vllm 部署GLM4模型进行 Zero-Shot 文本分类实验,让大模型给出分类原因,准确率可提高6%

简介 本文记录了使用 vllm 部署 GLM4-9B-Chat 模型进行 Zero-Shot 文本分类的实验过程与结果。通过对 AG_News 数据集的测试&#xff0c;研究发现大模型在直接进行分类时的准确率为 77%。然而&#xff0c;让模型给出分类原因描述&#xff08;reason&#xff09;后&#xff0c;…

HarmonyOS应用六之应用程序进阶二

目录&#xff1a; 一、进度条通知二、闹钟提醒2.1、在module.json5配置文件中开启权限2.2、导入后台代理提醒reminderAgentManager模块&#xff0c;将此模块命名为reminderAgentManager2.3、如果是新增提醒&#xff0c;实现步骤如下&#xff1a; 3、Native C交互4、第三方库的基…

使用IDEA和vecode创建vue项目并启动

一、使用IDEA创建Vue项目 一、打开IDEA下载Vue插件 打开IDEA的设置找到插件并查找到下载Vue.js这个插件 二、用IDEA创建Vue项目 新建项目并选择到Vue生成器 我这是IDEA自带的 创建项目非常迅速 端口号&#xff08;默认&#xff09;&#xff1a;5173 版本是3.x 启动项目…

使用scss生成旋转圆圈

图片 html代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>…

modbus tcp wireshark抓包

Modbus TCP报文详解与wireshark抓包分析_mbap-CSDN博客 关于wireshark无法分析出modbusTCP报文的事情_wireshark 协议一列怎么没有modbus tcp-CSDN博客 使用Wireshark过滤Modbus功能码 - 技象科技 连接建立以后才能显示Modbus TCP报文 modbus.func_code 未建立连接时&…

澳鹏干货 | 大语言模型的上下文窗口 (Context Windows)

大语言模型&#xff08;LLMs&#xff09;极大地提升了人工智能在理解和生成文本方面的能力。其中一个影响其效用的重要方面是“上下文窗口”&#xff08;Context Windows&#xff09;—— 这个概念直接影响着模型接收和生成语言的有效性。 本期澳鹏干货将深入探讨上下文窗口对…

AI 自学 Lesson1 - Sklearn(开源Python机器学习包)

目录 背景 作为 lesson1 的原因 一、Sklearn 概述 1. Sklearn 算法库 2. 主要组件 3. 核心流程 4. 自带数据集 二、Sklearn 实操&库名称总结 1. 数据导入 2.数据预处理 2.1 数据划分 2.2 数据变换操作 2.3 特征选择 3. 监督学习算法 3.1 监督学习算法-回归 …

手机控车系统是一种高科技的汽车智能控制系统?

手机控车系统概述 系统概述 移动管家手机控车系统集成了汽车安防、智能化控制及专业配置产品&#xff0c;采用了先进的生产检测设备和质控体系&#xff0c;确保产品质量。该系统支持手机远程控车、远程报警、卫星定位、无匙进入、一键启动、自动升窗等全面功能&#xff0c;为用…

Spark:DataFrame介绍及使用

1. DataFrame详解 DataFrame是基于RDD进行封装的结构化数据类型&#xff0c;增加了schema元数据&#xff0c;最终DataFrame类型在计算时&#xff0c;还是转为rdd计算。DataFrame的结构化数据有Row&#xff08;行数据&#xff09;和schema元数据构成。 Row 类型 表示一行数据 …

C++笔记之原子操作

C++笔记之原子操作 code review! 文章目录 C++笔记之原子操作1.初始化2.赋值3.取值4.赋给另一个原子类型5.`exchange`6.`compare_exchange_weak` 和 `compare_exchange_strong`使用场景7.注意事项在 C++ 中,原子类型提供了对共享变量的无锁操作,确保多线程环境下的安全。以下…

AI的风终于吹到到了短剧,也把财富的风吹到了家门口!

近年来&#xff0c;AI技术在短剧领域的创新应用&#xff0c;给整个行业带来了全新的变革。以快手平台为例&#xff0c;一部以**《山海经》为背景的短剧“李行舟”在今年7月13日上线后引发热议。** 这部短剧讲述了少年李行舟在大海中与古代神灵和各种异兽搏斗的故事。与传统影视…

【C++11】lambda表达式

前言&#xff1a; 随着 C11 的发布&#xff0c;C 标准引入了许多新特性&#xff0c;使语言更加现代化&#xff0c;开发者编写的代码也变得更加简洁和易于维护。Lambda 表达式是其中一个重要的特性&#xff0c;它提供了一种方便的方式来定义匿名函数&#xff0c;这在函数式编程范…

并发——笔试面试总结

1. 进程之间通信的途径有哪些&#xff1f;并说一下他们的通信机制原理 进程间通信的途径包括管道、消息队列、共享内存、信号量、套接字等&#xff0c;以下是几种常见的进程间通信方式及原理&#xff1a; (1) 管道(Pipe) 通信机制原理&#xff1a;管道是一种半双工的通信方式&a…