<jupyter_start><jupyter_text>在一个小城市里，有 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 ，其中：        1、houses[i]：是第 i 个房子的颜色，0 表示这个房子还没有被涂色。        2、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<jupyter_code>class Solution:
    def minCost(self, houses, cost, m: int, n: int, target: int) -> int:
        # dp[i][j][k] 将前 i 个房子，染成 j 个街区，并且第 i 个房子的颜色为 k 的 的最小花费
        dp = [[[float('inf')] * (1 + n)  for _  in range(1+target)] for _ in range(1 + m)]
        # 0 个街区 j 个 分区，是不现实的，因此都是 inf，同样 0 个街区，n 中 颜色，也是不合理的
        for i in range(n+1): # 0 个房子，0个街区，无论多少种颜色都是 0 中方案
            dp[0][0][i] = 0
        
        cost.insert(0, [0, 0])
        houses.insert(0, 0)
        for i in range(1, m+1):
            for j in range(1, min(i, target)+1):
                if houses[i] != 0:
                    c = houses[i]
                    for u in range(1, n+1):
                        if u == c:
                            dp[i][j][c] = min(dp[i][j][c], dp[i-1][j][u])
                        else:
                            dp[i][j][c] = min(dp[i][j][c], dp[i-1][j-1][u])
                else:
                    for k in range(1, n+1):
                        for u in range(1, n+1):
                            if u == k: # i 和 i-1 颜色涂的相同
                                dp[i][j][k] = min(dp[i][j][k], dp[i-1][j][k] + cost[i][k-1])
                            else: # i 和 i-1 颜色涂的相同
                                dp[i][j][k] = min(dp[i][j][k], dp[i-1][j-1][u] + cost[i][k-1])
        res = min(dp[-1][-1][:]) # 涂到最后一个房子，使用了 n 种配色，最后一个房子的颜色无所谓，最小花费就可以
        return res if res != float('inf') else -1 
                    c = houses[i]
                    for k in range(1, 1+n):
                        if k == c:
                            dp[i][i][k] = min(dp[i][j][k], dp[i-1][j][k]) 
                        else:
                            dp[i][i][k] = min(dp[i][j][k], dp[i-1][j-1][k]) 
solution = Solution()
solution.minCost([0,2,1,2,0],
[[1,10],[10,1],[10,1],[1,10],[5,1]],
5,
2,
3)
[[[0, 0, 0, 0], [inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf]], 
 [[inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf]], 
 [[inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf]], 
 [[inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf]], 
 [[inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf], [inf, inf, inf, inf]]]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2255598033861278, 'fraction_numerical': 0.06608410704533042, 'mean_word_length': 2.0123355263157894, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '314114', 'license': 'Apache-2.0', 'n_tokens_mistral': 1967, 'n_tokens_neox': 1943, 'n_words': 389, 'path': 'Dynamic Programming/1124/1473. Paint House III.ipynb', 'repo_name': 'YuHe0108/Leetcode', 'size': '3662'}