zoukankan      html  css  js  c++  java
  • [Locked] Paint House I & II

    Paint House

    There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.

    The cost of painting each house with a certain color is represented by a n x 3 cost matrix. For example, costs[0][0] is the cost of painting house 0 with color red; costs[1][2] is the cost of painting house 1 with color green, and so on... Find the minimum cost to paint all houses.

    Note:
    All costs are positive integers.

    分析:

      典型动态规划,通过遍历所有情况可以弥补前面的选择对后面的影响。时间复杂度为O(n*3*3) = O(n);利用滚动数组,空间复杂度为O(3*2) = O(1)。

    代码:

    int minCost2(vector<vector<int> > cost) {
        vector<int> opt(3, 0), temp(3, 0);
        for(int i = 0; i < cost.size(); i++) {
            for(int j = 0; j < 3; j++) {
                temp[j] = INT_MAX;
                for(int k = 0; k < 3; k++) {
                    if(j != k)
                        temp[j] = min(temp[j], opt[k] + cost[i][j]);
                }
            }
            opt.swap(temp);
        }
        int minc = INT_MAX;
        for(int i : opt)
            minc = min(minc ,i);
        return minc;
    }

    Paint House II

    There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.

    The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2]is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.

    Note:
    All costs are positive integers.

    Follow up:
    Could you solve it in O(nk) runtime?

    分析:

      如果采用I中的方法,时间复杂度为O(n*k*k),空间复杂度为O(k*2)。为了降低时间复杂度,可以通过减少两重k循环里的大量重复计算来使得O(k*k)的复杂度变为O(k)。此题中,对于j = j1, j2两种情况,它们的内部k循环有k-2次是重复比较了cost[i][j1] + x和cost[i][j2] + x的大小的,可以通过一次cost[i][j1]和cost[i][j2]的比较替代;扩展到j = 1...k种情况,只需找到小的cost[i][j], j = 1...k.

    解法:

      动态规划,第i轮的最小代价是j = j1时,假设第i + 1轮中,j = j1是默认剔除的,很简单,前一轮的结果后一轮的最小结果都应该使用的,那么第i + 1轮的最小代价是min(cost[i+1][j])的j的取值时;然而j = j1并不是默认剔除的,故在第i + 1轮是cost[i + 1][j1]是无法使用上一轮的最小结果的,但它应该使用第二小的结果,故只需要比较第i + 1轮中,j == j1和j != j1两种情况的值即可。时间复杂度为O(n*(k + 常数)) = O(nk),空间复杂度,利用滚动值存储中间结果,为O(1)

    代码:

    int minCost(vector<vector<int> > cost) {
        int min1 = 0, min2 = 0, record = -1, c = INT_MAX;
        for(int i = 0; i < cost.size(); i++) {
            int minval1 = INT_MAX, minval2 = INT_MAX, last = -1;
            for(int j = 0; j < cost[0].size(); j++) {
                if(record != j) {
                    if(minval1 > cost[i][j]) {
                        minval2 = minval1;
                        minval1 = cost[i][j];
                        last = j;
                    }
                    else
                        minval2 = min(minval2, cost[i][j]);
                }
            }
            int a = minval1 + min1, b = minval2 + min1;
            if(record != -1)
                c = cost[i][record] + min2;
            if(a < c) {
                record = last;
                min1 = a;
                min2 = min(b, c);
            }
            else {
                min1 = c;
                min2 = a;
            }
            
        }
        cout<<endl;
        return min1;
    }
  • 相关阅读:
    Windows Server环境下消息队列之ActiveMQ实战
    Javascript 面向对象编程(一):封装
    Python常用函数
    redis源码(一):为redis添加自己的列表类型
    导出数据到Excel表格
    Oracle————存储过程与函数
    Solr搜索引擎 — 通过mysql配置数据源
    redis的安装和使用【2】redis的java操作
    MySql(四)Select条件查询
    MySql (二)入门语句和基本操作
  • 原文地址:https://www.cnblogs.com/littletail/p/5203171.html
Copyright © 2011-2022 走看看