[LeetCode 256] Paint House

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 1with color green, and so on... Find the minimum cost to paint all houses. 

Note: All costs are positive integers.

Example

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

Paint House II

原文地址:https://www.cnblogs.com/lz87/p/6960888.html