ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode 5431. 给房子涂色 III(DP)

2020-06-09 09:01:32  阅读:318  来源: 互联网

标签:10 5431 houses cost 涂色 c1 III dp


1. 题目

在一个小城市里,有 m 个房子排成一排,你需要给每个房子涂上 n 种颜色之一(颜色编号为 1 到 n )。
有的房子去年夏天已经涂过颜色了,所以这些房子不需要被重新涂色。

我们将连续相同颜色尽可能多的房子称为一个街区。(比方说 houses = [1,2,2,3,3,2,1,1] ,它包含 5 个街区 [{1}, {2,2}, {3,3}, {2}, {1,1}] 。)

给你一个数组 houses ,一个 m * n 的矩阵 cost 和一个整数 target ,其中:

  • houses[i]:是第 i 个房子的颜色,0 表示这个房子还没有被涂色。
  • cost[i][j]:是将第 i 个房子涂成颜色 j+1 的花费。

请你返回房子涂色方案的最小总花费,使得每个房子都被涂色后,恰好组成 target 个街区。
如果没有可用的涂色方案,请返回 -1 。

示例 1:
输入:houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], 
m = 5, n = 2, target = 3
输出:9
解释:房子涂色方案为 [1,2,2,1,1]
此方案包含 target = 3 个街区,分别是 [{1}, {2,2}, {1,1}]。
涂色的总花费为 (1 + 1 + 1 + 1 + 5) = 9。

示例 2:
输入:houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], 
m = 5, n = 2, target = 3
输出:11
解释:有的房子已经被涂色了,在此基础上涂色方案为 [2,2,1,2,2]
此方案包含 target = 3 个街区,分别是 [{2,2}, {1}, {2,2}]。
给第一个和最后一个房子涂色的花费为 (10 + 1) = 11。

示例 3:
输入:houses = [0,0,0,0,0], cost = [[1,10],[10,1],[1,10],[10,1],[1,10]], 
m = 5, n = 2, target = 5
输出:5

示例 4:
输入:houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], 
m = 4, n = 3, target = 3
输出:-1
解释:房子已经被涂色并组成了 4 个街区,分别是 [{3},{1},{2},{3}] ,
无法形成 target = 3 个街区。
 
提示:
m == houses.length == cost.length
n == cost[i].length
1 <= m <= 100
1 <= n <= 20
1 <= target <= m
0 <= houses[i] <= n
1 <= cost[i][j] <= 10^4

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/paint-house-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • dp[i][c][j]表示刷完i号房子,其颜色为 c时,产生j个街区的最小花费
class Solution {
public:
    int minCost(vector<int>& houses, vector<vector<int>>& cost, int m, int n, int target) {
        int i, j, c1, c2, mincost = INT_MAX;
        vector<vector<vector<int>>> dp(m, vector<vector<int>>(n+1, vector<int>(m+1, INT_MAX)));
        //初始化,第一个房子的情况
        if(houses[0] != 0)//已经刷过了
            dp[0][houses[0]][1] = 0;
        else//没有刷
            for(c1 = 1; c1 < n+1; ++c1)
                dp[0][c1][1] = cost[0][c1-1];
		//其余房子
        for(i = 1; i < m; i++) 
        {
            for(c1 = 1; c1 < n+1; c1++)//前一个房子的颜色
            {
                for(j = 1; j < m; j++)//几个 block
                {
                    if(dp[i-1][c1][j] == INT_MAX)
                        continue;
                    if(houses[i] != 0)//已经刷过颜色,没有费用
                    {
                        if(houses[i] == c1)//跟前一家颜色一样,街区不增加
                            dp[i][houses[i]][j] = min(dp[i][houses[i]][j], dp[i-1][c1][j]);
                        else
                            dp[i][houses[i]][j+1] = min(dp[i][houses[i]][j+1], dp[i-1][c1][j]);
                    }
                    else//没有刷过颜色
                        for(c2 = 1; c2 < n+1; c2++)//当前房子的颜色
                        {
                            if(c1 == c2)//跟前一家颜色一样,街区不增加,费用增加
                                dp[i][c2][j] = min(dp[i][c2][j], dp[i-1][c1][j]+cost[i][c2-1]);
                            else
                                dp[i][c2][j+1] = min(dp[i][c2][j+1], dp[i-1][c1][j]+cost[i][c2-1]);
                        }
                }
            }
        }
        for(c1 = 1; c1 < n+1; c1++)
            mincost = min(mincost, dp[m-1][c1][target]);
        return mincost==INT_MAX ? -1 : mincost;
    }
};

100 ms 16.9 MB

标签:10,5431,houses,cost,涂色,c1,III,dp
来源: https://blog.csdn.net/qq_21201267/article/details/106606529

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有