package com.interview.dynamic;
/**
* Paint House
* https://leetcode.com/problems/paint-house/
* https://leetcode.com/problems/paint-house-ii/
*/
public class PaintHouse {
public int minCostTopDownPainHouse1or2(int[][] costs) {
if (costs.length == 0) {
return 0;
}
int[][] dp = new int[costs.length][3];
return minCostUtil(costs, 0, -1, 3, dp);
}
private int minCostUtil(int[][] costs, int house, int prevColor, int k, int[][] dp) {
if (house == costs.length) {
return 0;
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < k; i++) {
if (i == prevColor) {
continue;
}
int val;
if (dp[house][i] != 0) {
val = dp[house][i];
} else {
val = costs[house][i] + minCostUtil(costs, house + 1, i, k, dp);
dp[house][i] = val;
}
min = Math.min(min, val);
}
return min;
}
public int minCostBottomUpPaintHouse2(int[][] costs) {
if (costs.length == 0 || costs[0].length == 0) {
return 0;
}
int[][] dp = new int[costs.length][costs[0].length];
for (int i = 0; i < costs[0].length; i++) {
dp[0][i] = costs[0][i];
}
for (int i = 1; i < costs.length; i++) {
Pair p = findMinSecondMin(dp[i - 1]);
for (int j = 0; j < costs[0].length; j++) {
dp[i][j] = costs[i][j];
if (j == p.minIndex) {
dp[i][j] += dp[i-1][p.secondMinIndex];
} else {
dp[i][j] += dp[i-1][p.minIndex];
}
}
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < dp[0].length; i++) {
min = Math.min(min, dp[dp.length - 1][i]);
}
return min;
}
class Pair {
int minIndex;
int secondMinIndex;
}
private Pair findMinSecondMin(int[] input) {
int minIndex;
int secondMinIndex;
if (input[0] < input[1]) {
minIndex = 0;
secondMinIndex = 1;
} else {
minIndex = 1;
secondMinIndex = 0;
}
for (int i = 2; i < input.length; i++) {
if (input[i] < input[minIndex]) {
secondMinIndex = minIndex;
minIndex = i;
} else if (input[i] < input[secondMinIndex]) {
secondMinIndex = i;
}
}
Pair p = new Pair();
p.minIndex = minIndex;
p.secondMinIndex = secondMinIndex;
return p;
}
public static void main(String args[]) {
PaintHouse ph = new PaintHouse();
int[][] input = {{1, 2, 1}, {1, 4, 5}, {2, 6, 1}, {3, 3, 2}};
System.out.println(ph.minCostBottomUpPaintHouse2(input));
}
}