zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
  • 相关阅读:
    71 是否同一棵二叉搜索树(25 分)
    75 平衡二叉树的根(25 分)
    72 树种统计(25 分)
    2018(容斥定理 HDU6286)
    直观的理解计算机中的数值编码
    如何关闭emacs开启时自己打开的欢迎界面
    图论:最短路径:广度优先搜索(C语言实现)
    ubunut 14.04 将Caps Lock设置为Control
    邻接表:C语言实现
    队列(C语言实现)
  • 原文地址:https://www.cnblogs.com/reboot329/p/6127979.html
Copyright © 2011-2022 走看看