256. Paint House

比较典型的动态规划。

如果把重点放在当前房子和上一个相同,还是不同来做就做不出来,所以干脆枚举每个房子的情况。

dp[i][0] = costs[i][0] + Math.min(dp[i-1][1],dp[i-1][2]);
dp[i][1] = costs[i][1] + Math.min(dp[i-1][0],dp[i-1][2]);
dp[i][2] = costs[i][2] + Math.min(dp[i-1][1],dp[i-1][0]);

然后其实A B C用3个变量记录上一个房子的3种情况就行了,不用数组。

public class Solution 
{
    public int minCost(int[][] costs) 
    {
        int num = costs.length;
        if(num == 0) return 0;
        
        int a = costs[0][0];
        int b = costs[0][1];
        int c = costs[0][2];
        
        for(int i = 1; i < num;i++)
        {
            int a2,b2,c2;
            a2 = costs[i][0] + Math.min(b,c);
            b2 = costs[i][1] + Math.min(a,c);
            c2 = costs[i][2] + Math.min(a,b);
            a = a2; b = b2; c = c2;
        }
        
        return Math.min(Math.min(a,b),c);
    }
}

动态规划是坑啊,想了半天没想到这么简单。。


二刷。

N的状态与N-1有关。

比较triky的时候每一步的三个种情况都要算下来。

N选绿,看n-1是蓝好还是红好。
N选哄,看 ....蓝......绿..。
...蓝,.......红......绿..。

最后看n选红绿蓝比较下就行。。

Time: O(n)
Space: O(1) (有人指出可以without extra space...在原数组上修改。。。。)

public class Solution {
    public int minCost(int[][] costs) {
        if (costs.length == 0) return 0;
        if (costs.length == 1) return Math.max(Math.max(costs[0][1], costs[0][0]), costs[0][2]);
        
        int[] red = new int[2];
        int[] green = new int[2];
        int[] blue = new int[2];
        
        red[0] = costs[0][0];
        blue[0] = costs[0][1];
        green[0] = costs[0][2];
        
        
        for (int i = 1; i < costs.length; i++) {
            red[i%2] = Math.min(green[(i-1)%2], blue[(i-1)%2]) + costs[i][0];
            blue[i%2] = Math.min(red[(i-1)%2], green[(i-1)%2]) + costs[i][1];
            green[i%2] = Math.min(red[(i-1)%2], blue[(i-1)%2]) + costs[i][2];
        }
        int len = costs.length - 1;
        return Math.min(red[len%2], Math.min(blue[len%2], green[len%2]));
    }
}
原文地址:https://www.cnblogs.com/reboot329/p/5951451.html