题目描述
假如有一排房子,共nnn个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个n∗3n * 3n∗3的正整数矩阵costscostscosts来表示的。
例如,costs[0][0]costs[0][0]costs[0][0]表示第000号房子粉刷成红色的成本花费;costs[1][2]costs[1][2]costs[1][2]表示第111号房子粉刷成绿色的花费,以此类推。
请计算出粉刷完所有房子最少的花费成本。
示例 1:
输入: costs = [[17,2,17],[16,16,5],[14,3,19]]
输出: 10
解释: 将 0 号房子粉刷成蓝色,1 号房子粉刷成绿色,2 号房子粉刷成蓝色。最少花费: 2 + 5 + 3 = 10。
算法原理
确定状态表示:由于iii号房子可以粉刷红,蓝,绿三种颜色,一共是三种状态,所以dpdpdp数组是一个具有三列的二维数组
- dp[i][0]dp[i][0]dp[i][0]表示iii号房子粉刷红色时的最小花费
- dp[i][1]dp[i][1]dp[i][1]表示iii号房子粉刷蓝色时的最小花费
- dp[i][2]dp[i][2]dp[i][2]表示iii号房子粉刷绿色时的最小花费
确定状态转移方程:
- 当iii号房子粉刷红色时,i−1i-1i−1号房子只能粉刷蓝色或者绿色,所以dp[i][0]dp[i][0]dp[i][0]应该等于i−1i - 1i−1号房子分别粉刷蓝色,绿色时的最小花费的最小值加上iii号房子粉刷红色的价格min(dp[i−1][1],dp[i−1][2])+costs[i][0]min(dp[i-1][1], dp[i-1][2]) + costs[i][0]min(dp[i−1][1],dp[i−1][2])+costs[i][0]
- 当iii号房子粉刷蓝色时,i−1i-1i−1号房子只能粉刷红色或者绿色,所以dp[i][1]dp[i][1]dp[i][1]应该等于i−1i - 1i−1号房子分别粉刷红色,绿色时的最小花费的最小值加上iii号房子粉刷蓝色的价格min(dp[i−1][0],dp[i−1][2])+costs[i][1]min(dp[i-1][0], dp[i-1][2]) + costs[i][1]min(dp[i−1][0],dp[i−1][2])+costs[i][1]
- 当iii号房子粉刷绿色时,i−1i-1i−1号房子只能粉刷红色或者蓝色,所以dp[i][2]dp[i][2]dp[i][2]应该等于i−1i - 1i−1号房子分别粉刷红色,蓝色时的最小花费的最小值加上iii号房子粉刷绿色的价格min(dp[i−1][0],dp[i−1][1])+costs[i][2]min(dp[i-1][0], dp[i-1][1]) + costs[i][2]min(dp[i−1][0],dp[i−1][1])+costs[i][2]
初始化:根据状态转移方程,dp[0][0],dp[0][1],dp[0][2]dp[0][0],dp[0][1],dp[0][2]dp[0][0],dp[0][1],dp[0][2]在填的时候会越界,所以初始化它们dp[0][0]=costs[0][0],dp[0][0]=costs[0][1],dp[0][0]=costs[0][2]dp[0][0] = costs[0][0],dp[0][0] = costs[0][1],dp[0][0] = costs[0][2]dp[0][0]=costs[0][0],dp[0][0]=costs[0][1],dp[0][0]=costs[0][2]
填表顺序:由于一个房子粉刷三个颜色的最小花费都需要知道,所以要从上到下,一行一起填
返回值:最后一个房子粉刷三个不同颜色的最小花费的最小值min(dp[n−1][0],dp[n−1][1],dp[n−1][2])min(dp[n-1][0], dp[n-1][1], dp[n-1][2])min(dp[n−1][0],dp[n−1][1],dp[n−1][2])
代码
classSolution{public:intminCost(vector<vector<int>>&costs){intn=costs.size();vector<vector<int>>dp(n,vector<int>(3,0));dp[0][0]=costs[0][0],dp[0][1]=costs[0][1],dp[0][2]=costs[0][2];for(inti=1;i<n;++i){// 粉刷红色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];}returnmin({dp[n-1][0],dp[n-1][1],dp[n-1][2]});}};