题目
一排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]));}}