文章目录
一、题目
二、思路
(1)确定状态:
已知不同房子刷成不同颜色的价格矩阵cost
,加上这种只需要求出【最值】的题目经常使用dp;因为每个房子能刷成三种颜色,即三种状态,加上不同的房子位置这个维度,可以令 d p [ j ] [ i ] dp[j][i] dp[j][i]二维数组(其中j
取值为0,1,2)表示:第 i i i个房子粉刷为颜色j
,并且这前i
个房子的粉刷情况都是符合题意时,这i
个房子所需要的最少话费成本。
(2)状态转移方程 d p [ i ] [ 0 ] = min ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 2 ] ) + costs [ i ] [ 0 ] d p [ i ] [ 1 ] = min ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 2 ] ) + costs [ i ] [ 1 ] d p [ i ] [ 2 ] = min ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] ) + costs [ i ] [ 2 ] \begin{aligned} d p[i][0] & =\min (d p[i-1][1], d p[i-1][2])+\operatorname{costs}[i][0] \\ d p[i][1] & =\min (d p[i-1][0], d p[i-1][2])+\operatorname{costs}[i][1] \\ d p[i][2] & =\min (d p[i-1][0], d p[i-1][1])+\operatorname{costs}[i][2] \end{aligned} dp[i][0]dp[i][1]dp[i][2]=min(dp[i−1][1],dp[i−1][2])+costs[i][0]=min(dp[i−1][0],dp[i−1][2])+costs[i][1]=min(dp[i−1][0],dp[i−1][1])+costs[i][2]神奇的是三个方程可以通过求余方法合为一个: d p [ i ] [ j ] = min ( d p [ i − 1 ] [ ( j + 1 ) m o d 3 ] , d p [ i − 1 ] [ ( j + 2 ) m o d 3 ] ) + costs [ i ] [ j ] d p[i][j]=\min (d p[i-1][(j+1) \bmod 3], d p[i-1][(j+2) \bmod 3])+\operatorname{costs}[i][j] dp[i][j]=min(dp[i−1][(j+1)mod3],dp[i−1][(j+2)mod3])+costs[i][j]计算到最后一个房子时,即 d p [ n − 1 ] [ j ] dp[n-1][j] dp[n−1][j]数组的三个数的最小值为按规矩粉刷房子的最小总成本。因为当 i ≥ 1 i \geq 1 i≥1时, d p [ i ] dp[i] dp[i]的计算只和 d p [ i − 1 ] dp[i-1] dp[i−1]有关,所以可以使用【滚动数组】优化计算复杂度,这个滚动数组即大小为颜色种类数。
(3)初始状态 + 边界情况
第0个房子左边木有房子,直接赋值当前房子的三种初值, d p [ k ] = c o s t s [ 0 ] [ k ] dp[k] = costs[0][k] dp[k]=costs[0][k]。
(4)遍历顺序:i
和j
都是从小到大遍历。
三、cpp代码
class Solution {
public:
int minCost(vector<vector<int>>& costs) {
int n = costs.size();
vector<int>dp(3);
//初始条件赋值
for(int k = 0; k < 3; k++){
dp[k] = costs[0][k];
}
//状态转移方程
for(int i = 1; i < n; i++){
vector<int> temp_vec(3);
for(int j = 0; j < 3; j++){
temp_vec[j] = min(dp[(j+1)%3], dp[(j+2)%3]) + costs[i][j];
}
dp = temp_vec;
}
auto ans_it = min_element(dp.begin(), dp.end());
return *ans_it;
}
};
四、Python代码
class Solution:
def minCost(self, costs: List[List[int]]) -> int:
# 赋值数组,简洁
dp = costs[0]
for i in range(1, len(costs)):
temp_dp = []
for j in range(3):
temp_dp.append(min(dp[(j+1)%3], dp[(j+2)%3]) + costs[i][j])
dp = temp_dp
return min(dp)