目录
- 动态规划分析问题五步曲
- 题目概述
- 代码编写
动态规划分析问题五步曲
不清楚动态规划分析问题是哪关键的五步的少年们可以移步到
链接: 动态规划算法基础
这篇文章非常详细的介绍了动态规划算法是如何分析和解决问题的
题目概述
链接: 粉刷房子
- 状态表示(题目要求+自己的经验)
本题状态:分析第i个位置,发现第i个位置可以选择红色,蓝色和绿色
显然,一个状态表示是不够的得分类讨论
red[i] : 表示i个位置粉刷为红色的最小花费
blue[i] : 表示i个位置粉刷为蓝色的最小花费
green[i] : 表示i个位置粉刷为绿色的最小花费
- 状态转移方程推导
对i位置进行分类讨论,若i位置一直颜色,则其他i-1的颜色坑定为 其他两种颜色的一种
轻松得出状态转移方程
- 初始化(防止越界+结合状态表示初始化)
根据状态转移方程,当i = 0时会发生越界
根据状态表示 :
初始化令red = cost[0][0] , blue = cost[0][1] , green = cost[0][2];
- 填表顺序(分析要填i位置前一个依赖状态的位置)
本题三个dp表显然都是从左到右填表
- 返回值(由题目要求来)
因此我们并不确定最终位置会染成什么颜色,又根据三个表的状态表示
只需要返回 三者的最小值即可
代码编写
有了动态规划五步曲我们就可以写出非常优雅的代码了
int minCost(vector<vector<int>>& costs) {int n = costs.size();vector<int> red(n);auto blue = red , green = red;red[0] = costs[0][0],blue[0] = costs[0][1],green[0] = costs[0][2];for(int i = 1 ; i < n ; i++){red[i] = min(blue[i-1],green[i-1]) + costs[i][0];blue[i] = min(red[i-1],green[i-1]) + costs[i][1];green[i] = min(red[i-1],blue[i-1]) + costs[i][2];}return min(red[n-1],min(blue[n-1],green[n-1]));}
少年,今天你又进步了一点点哟,明天继续加油吧