【学会动态规划】剑指 Offer II 091. 粉刷房子(14)

目录

动态规划怎么学?

1. 题目解析

2. 算法原理

1. 状态表示

2. 状态转移方程

3. 初始化

4. 填表顺序

5. 返回值

3. 代码编写

写在最后:


动态规划怎么学?

学习一个算法没有捷径,更何况是学习动态规划,

跟我一起刷动态规划算法题,一起学会动态规划!

1. 题目解析

题目链接:剑指 Offer II 091. 粉刷房子 - 力扣(Leetcode)

【学会动态规划】剑指 Offer II 091. 粉刷房子(14)_第1张图片

 这道题看起来挺复杂,其实题目很好理解,

我们来看第一个示例:

这里一共有三个子数组,代表的是三栋相邻的房子,

上面的数字就是刷不同颜色需要的花费金钱,

而题目要我们求的就是刷完所有房子最低的花费,

然后这里有一个条件限制,就是相邻的两个房子刷的颜色不能相同。 

2. 算法原理

1. 状态表示

根据题目,我们可以得出三个状态表示:

dp[ i ][ 0 ] 表示粉刷到 i 位置的时候,最后一个位置刷上红色,此时的最小花费

dp[ i ][ 1 ] 表示粉刷到 i 位置的时候,最后一个位置刷上蓝色,此时的最小花费

dp[ i ][ 2 ] 表示粉刷到 i 位置的时候,最后一个位置刷上绿色,此时的最小花费

2. 状态转移方程

所以,状态转移方程也是由这三种情况得来的:

最后一个房子选红色,他的最小花费就是上一个房子选蓝色和绿色花费的最小值+当前房子的花费

其他的同理:

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 ][ 0 ],dp[ i - 1 ][ 1 ] ) + costs[ i ][ 2 ]

3. 初始化

为了防止越界, 且不能让后面的值出错,

实际上填0就行了。

4. 填表顺序

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

5. 返回值

返回:min( dp[ n ][ 0 ],min( dp[ n ][ 1 ],dp[ n ][ 2 ] ) )

3. 代码编写

class Solution {
public:
    int minCost(vector>& costs) {
        int n = costs.size();
        vector> dp(n + 1, vector(3));
        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][0], dp[i - 1][1]) + costs[i - 1][2];
        }
        return min(dp[n][0], min(dp[n][1], dp[n][2]));
    }   
};

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果感到有所收获的话可以给博主点一个哦。

如果文章内容有遗漏或者错误的地方欢迎私信博主或者在评论区指出~

你可能感兴趣的:(学会动态规划,动态规划,算法,学习,c++)