一排n幢房子要粉刷成红色、绿色和蓝色,不同房子被粉刷成不同颜色的成本不同。用一个n×3的数组表示n幢房子分别用3种颜色粉刷的成本。要求任意相邻的两幢房子的颜色都不一样,请计算粉刷这n幢房子的最少成本。例如,粉刷3幢房子的成本分别为[[17,2,16],[15,14,5],[13,3,1]],如果分别将这3幢房子粉刷成绿色、蓝色和绿色,那么粉刷的成本是10,是最少的成本。
用i表示房子,f(颜色)(i)表示最小花费,costs[][]表示当前房子当前颜色的话费
f(颜色)(i) = Math.min( f(其他颜色)(i-1) , f(其他颜色)(i-1) ) + costs[当前房子][当前颜色]
public class Test {
public static void main(String[] args) {
int[][] costs = {
{17, 2, 16},
{15, 14, 5},
{13, 3, 1}};
int result = minCost(costs);
System.out.println(result);
}
public static int minCost(int[][] costs) {
if (costs.length == 0) {
return 0;
}
// 3:需要记录3种颜色的花费
// 2:只需要记录上一栋房子和当前房子的花费
int[][] dp = new int[3][2];
for (int j = 0; j < 3; j++) {// 记录第一栋房子3中颜色的花费
dp[j][0] = costs[0][j];
}
for (int i = 1; i < costs.length; i++) {// 遍历房子
for (int j = 0; j < 3; j++) {// 遍历颜色
// [(j+2)%3]:其他颜色的意思
// [(i-1)%2]:上一栋房子的意思
int prev1 = dp[(j + 2) % 3][(i - 1) % 2];
int prev2 = dp[(j + 1) % 3][(i - 1) % 2];
dp[j][i % 2] = Math.min(prev1, prev2) + costs[i][j];
}
}
int last = (costs.length - 1) % 2;// 最后的房子
// dp[0][last]、dp[1][last]、dp[2][last]:表示3种颜色,取最小值
return Math.min(dp[0][last], Math.min(dp[1][last], dp[2][last]));
}
}