问题描述:
There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.
The cost of painting each house with a certain color is represented by a n x k
cost matrix. For example, costs[0][0]
is the cost of painting house 0 with color 0; costs[1][2]
is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.
Note:
All costs are positive integers.
Example:
Input: [[1,5,3],[2,9,4]] Output: 5 Explanation: Paint house 0 into color 0, paint house 1 into color 2. Minimum cost: 1 + 4 = 5; Or paint house 0 into color 2, paint house 1 into color 0. Minimum cost: 3 + 2 = 5.
Follow up:
Could you solve it in O(nk) runtime?
解题思路:
题目要求求最小的花费,我们会首先想到动态规划。
题目中要求的是相邻的两个房子的颜色不能相等, 若我们给当前第i个房子涂上颜色j, 则代表第i-1个房子不能涂颜色j
我们可以用数组lowest[j]表示涂到当前房屋除了涂j个颜色在其他选择中最小的花费。
则我们在计算下一个房子涂颜色j时的总花费为:lowest[j] + costs[i][j]
所以我们在每一次计算完这个房子所有可能的耗费后,要更新lowest为当前房子的情况。
需要注意的是,这样比较不能涵盖只有一个房子和一个颜色的情况,所以需要单独列出来。
代码:
class Solution { public: int minCostII(vector<vector<int>>& costs) { int n = costs.size(); if(n == 0) return 0; int m = costs[0].size(); if(m == 0) return 0; if(m == 1 && n == 1) return costs[0][0]; vector<int> lowest(m, 0); for(int i = 0; i < n; i++){ vector<int> temp(m, INT_MAX); for(int j = 0; j < m; j++){ lowest[j] += costs[i][j]; if(j > 0){ temp[j] = min(temp[j-1], lowest[j-1]); } } int low = lowest[m-1]; for(int j = m-2; j > -1; j--){ temp[j] = min(temp[j], low); low = min(low, lowest[j]); } lowest = temp; } int ret = lowest[0]; for(int i = 0; i < m; i++){ ret = min(ret, lowest[i]); } return ret; } };