题目来源
本题来源为:
题目描述
假如有一排房子,共 n 个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n x 3 的正整数矩阵 costs 来表示的。
例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2] 表示第 1 号房子粉刷成绿色的花费,以此类推。
请计算出粉刷完所有房子最少的花费成本。
题目解析
算法原理
1.状态表示
经验+题目要求
2.状态转移方程
先分析一种情况:
i位置是红色,那么i-1位置要么绿色要么蓝色,以此内推:
因此状态方程为:
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];
3.初始化
只有0位置会发生越界访问,因此我们要初始化0位置的值
这里我们可以加一个虚拟头节点的方式来进行初始化:
4.填表顺序
从左往右填表,依次填表
5.返回值
返回
代码实现
动态规划的代码基本就是固定的四步:
1.创建dp表 2.初始化 3.填表 4.返回值
本题完整代码实现:
class Solution { public: int minCost(vector<vector<int>>& costs) { int n=costs.size(); //创建dp表 vector<vector<int>> dp(n+1,vector<int>(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][1],dp[i-1][0])+costs[i-1][2]; } return min(dp[n][0],min(dp[n][1],dp[n][2])); } };