265. Paint House II


July-25-2019

DP题做了几道我也发现共性了,就是每道我都不会。
这道题要这么想:
n位置的最优解是cost[n]里最小的+best[n-1]。问题出在,当前K中里最便宜的情况,有可能和n-1最优解时的颜色一样,在遍历cost[0~k]的时候,如果颜色和上次最优解一样,就要当前COST+n-1的次优解。
所以每次需要记录的:最优解,次优解,和这次的颜色。
题里说单独位置每种颜色价钱不一样。这里其实我没想明白,假如有一样的情况,有可能某位置出现3个最优解,下个位置就没法保证选的是正确的颜色,因为解可能在忽略的第三种里?因为我觉得如果有2个最优解,是无所谓的= =因为无非颜色是和上次的最优相同,或者不同,只要保证不同就行了。
不知道想的对不对。

    public int minCostII(int[][] costs) {
        if (costs.length == 0) return 0;
        
        int prevMin1 = 0;
        int prevMin2 = 0;
        int prevColor = -1;
        
        for (int i = 0; i < costs.length; i ++) {
            int tempMin1 = Integer.MAX_VALUE;
            int tempMin2 = Integer.MAX_VALUE;
            int tempColor = -1;
            for (int j = 0; j < costs[i].length; j ++) {
                
                int costWithPrev = costs[i][j];
                costWithPrev += j == prevColor ? prevMin2 : prevMin1;

                if (costWithPrev < tempMin1) {
                    tempMin2 = tempMin1;
                    tempMin1 = costWithPrev;
                    tempColor = j;
                } else if (costWithPrev < tempMin2) {
                    tempMin2 = costWithPrev;
                }
            }
            prevMin1 = tempMin1;
            prevMin2 = tempMin2;
            prevColor = tempColor;
        }
        
        return prevMin1;
    }


从3个颜色换成K个了。

按上一题的思路走,就是维护K个结果,最后再选。

但是做起来谈何容易。。。

N个房子,每一步都要算K个结果(K-1个),然后每个结果都要比较(k-1)里面最小的,最终是n * k * k

说O(nk)的解法。

维护2个量,当前最小,当前第二小。。这种思路一般是不行的,但是此题是非一即二,只能和前面颜色相同或者不同,所以维护2个是可以的。

如果和前面颜色不同,我们就选当前最小;相同就退而求其次,选第二小,不可能既和前一个颜色相同,又不同。

所以需要记录2个最小量,还要记录前一层是啥鸡巴颜色,每次的值要先和最小的比较,再和第二小的比较,维护两个量。

最终结果是最小的。

public class Solution {
    public int minCostII(int[][] costs) {
        if (costs.length == 0) return 0;
        
        int prevColor = -1;
        int min1 = 0;
        int min2 = 0;
        for (int i = 0; i < costs.length; i++) {
            
            int prevMin1 = Integer.MAX_VALUE;
            int prevMin2 = Integer.MAX_VALUE;
            int tempColor = -1;
            
            for (int j = 0; j < costs[i].length; j++) {
                int temp = 0;
                
                // local min cost
                if (j != prevColor) {
                    temp = min1;
                } else {
                    temp = min2;
                }
                temp += costs[i][j];
                
                // if this localMin is also global?
                if (temp < prevMin1) {
                    prevMin2 = prevMin1;
                    prevMin1 = temp;
                    tempColor = j;
                } else if (temp < prevMin2) {
                    prevMin2 = temp;
                }
            }
            
            // update
            prevColor = tempColor;
            min1 = prevMin1;
            min2 = prevMin2;
        }
        
        return min1;
    }
}
原文地址:https://www.cnblogs.com/reboot329/p/6127979.html