题目链接: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]);}
};