LintCode_516 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 0costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.

 Notice

All costs are positive integers.

Example

Given n = 3, k = 3, costs = [[14,2,11],[11,14,5],[14,3,10]]return 10

house 0 is color 2, house 1 is color 3, house 2 is color 2,2 + 5 + 3 = 10

Challenge 

Could you solve it in O(nk)?

思路dp没的说啊, 关键是搞到O(nk);

其实对于一个颜色来说, 如果前面同色的最小值不是它的话, 就是最小值加上花费,

如果是同色的话, 前面第二小加上花费就行了, 果断O(nk)了。

class Solution {
public:
    /**
     * @param costs n x k cost matrix
     * @return an integer, the minimum cost to paint all houses
     */
    int minCostII(vector<vector<int>>& costs) {
        // Write your code here
        if (costs.empty()) {
            return 0;
        }
        const int n = costs.size();
        const int k = costs[0].size();
        int dp[n][k];
        int fir_min_val[n];
        int fir_min_color[n];
        int sec_min_val[n];
        memset(fir_min_val, 10000, sizeof(fir_min_val));
        memset(fir_min_color, -1, sizeof(fir_min_color));
        memset(sec_min_val, 10000, sizeof(sec_min_val));
        for (int i = 0; i < n; i++) {
            if ( i == 0) {
                for (int j = 0; j < k; j++) {
                    dp[i][j] = costs[i][j];
                }
            } else {
                for (int j = 0; j < k; j++) {
                    if (j != fir_min_color[ i - 1]) {
                        dp[i][j] = fir_min_val[i - 1] + costs[i][j];
                    } else {
                        dp[i][j] = sec_min_val[i - 1] + costs[i][j];
                    }
                }
            }
            for (int j = 0; j < k; j++) {
                if (dp[i][j] < fir_min_val[i]) {
                    sec_min_val[i] = fir_min_val[i];
                    fir_min_val[i] = dp[i][j];
                    fir_min_color[i] = j;
                } else {
                    if (dp[i][j] < sec_min_val[i]) {
                        sec_min_val[i] = dp[i][j];
                    }
                }
            }
        }
        return fir_min_val[n - 1];
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值