There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. 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 3
cost matrix. For example, costs[0][0]
is the cost of painting house 0
with color red; costs[1][2]
is the cost of painting house 1
with color green, and so on... Find the minimum cost to paint all houses.
Note: All costs are positive integers.
Given costs
= [[14,2,11],[11,14,5],[14,3,10]]
return 10
house 0 is blue, house 1 is green, house 2 is blue, 2 + 5 + 3 = 10
Solution 1. Brute force dfs recursion
Optimal substructure:
If the ith house is painted in color j, the min cost we can have is
f(i, j) = costs[i][j] + Math.min(f(i - 1, (j + 1) % 3), f(i - 1, (j + 2) % 3));
so the min cost of painting house [0.....i] is
f(i, j) = costs[i][j] + Math.min(f(i - 1, (j + 1) % 3), f(i - 1, (j + 2) % 3)) for j = 0, 1, 2;
If we draw the recursion tree, we get easily see there are a lot of redundant work.
1 public class Solution { 2 public int minCost(int[][] costs) { 3 if(costs == null || costs.length == 0 || costs[0].length != 3){ 4 return 0; 5 } 6 int totalHouseNumber = costs.length; 7 int min = Integer.MAX_VALUE; 8 for(int colorIdx = 0; colorIdx < 3; colorIdx++){ 9 min = Math.min(min, minCostRecur(costs, totalHouseNumber - 1, colorIdx)); 10 } 11 return min; 12 } 13 private int minCostRecur(int[][] costs, int houseIdx, int colorIdx){ 14 if(houseIdx < 0){ 15 return 0; 16 } 17 return costs[houseIdx][colorIdx] 18 + Math.min(minCostRecur(costs, houseIdx - 1, (colorIdx + 1) % 3), 19 minCostRecur(costs, houseIdx - 1, (colorIdx + 2) % 3)); 20 } 21 }
Solution 2. Dynamic Programming
State:
T[i][j]: the min cost of painting the first i houses with the ith house painted in color j.
Function:
T[i][j] = costs[i - 1][j] + Math.min(T[i - 1][(j + 1)%3], T[i - 1][(j + 2)%3]);
Initialization:
T[0][j] = 0, for j = 0, 1, 2; //cost 0 when there is no house to paint
Answer:
max of T[n][j] for j = 0, 1, 2;
1 public class Solution { 2 /** 3 * @param costs n x 3 cost matrix 4 * @return an integer, the minimum cost to paint all houses 5 */ 6 public int minCost(int[][] costs) { 7 if(costs == null || costs.length == 0 || costs[0].length != 3){ 8 return 0; 9 } 10 int n = costs.length; 11 int[][] T = new int[n + 1][3]; 12 for(int j = 0; j < 3; j++){ 13 T[0][j] = 0; 14 } 15 for(int i = 1; i <= n; i++){ 16 for(int j = 0; j < 3; j++){ 17 T[i][j] = costs[i - 1][j] + Math.min(T[i - 1][(j + 1)%3], T[i - 1][(j + 2)%3]); 18 } 19 } 20 int min = Integer.MAX_VALUE; 21 for(int j = 0; j < 3; j++){ 22 min = Math.min(min, T[n][j]); 23 } 24 return min; 25 } 26 }
Related Problems