There is a row of m houses in a small city, each house must be painted with one of the n colors (labeled from 1 to n), some houses that have been painted last summer should not be painted again.
A neighborhood is a maximal group of continuous houses that are painted with the same color.
For example: houses = [1,2,2,3,3,2,1,1] contains 5 neighborhoods [{1}, {2,2}, {3,3}, {2}, {1,1}].
Given an array houses, an m x n matrix cost and an integer target where:
houses[i]: is the color of the house i, and 0 if the house is not painted yet.
cost[i][j]: is the cost of paint the house i with the color j + 1.
Return the minimum cost of painting all the remaining houses in such a way that there are exactly target neighborhoods. If it is not possible, return -1.
Example 1:
Input: houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
Output: 9
Explanation: Paint houses of this way [1,2,2,1,1]
This array contains target = 3 neighborhoods, [{1}, {2,2}, {1,1}].
Cost of paint all houses (1 + 1 + 1 + 1 + 5) = 9.
Example 2:
Input: houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
Output: 11
Explanation: Some houses are already painted, Paint the houses of this way [2,2,1,2,2]
This array contains target = 3 neighborhoods, [{2,2}, {1}, {2,2}].
Cost of paint the first and last house (10 + 1) = 11.
houses数组中的数字表示第i 个房子的颜色,一共m个房子。
把连续相同颜色的分为1组,那么houses = [1,2,2,3,3,2,1,1] 这种的就分为5组 [{1}, {2,2}, {3,3}, {2}, {1,1}].
现在要把houses分成target个组,就需要把houses刷上不同的颜色以达到目的,
cost中就有n个颜色,cost = [[1,10],[10,1],[10,1],[1,10],[5,1]]这个的意思就是给第1个房子刷颜色1需要的cost是1,刷颜色2的cost是10,
同样的,给第2个房子刷1的cost是10,刷2cost是1,cost[i][j]就是第i个房子刷j+1颜色的cost
如果第i 个house已经有颜色(house[i] != 0), 保持原来的颜色,不再刷新的颜色。是0才能刷新的颜色。
求能分为target个组需要的cost, 如果不能达到,返回-1.
思路:
DP
变量较多,属于高维度DP,比较有难度。
先理一下变量,总的来说有3个变量,m个房子,n种颜色,要分为target个组。
定义dp[target+1][m+1][n+1]
首先,m和n都是>=1的,那么在它们为0时是不需要刷颜色的,cost=0
所以dp[0][0][*] = 0.
然后来看状态转移:
dp[k][i][ci] 表示 把house分为k个组,用前 i 个房子,第i个房子的颜色为ci,需要的cost
现在从dp[k-1][i-1][c_i-1]出发,假如第 i 个颜色 ci != c_i-1,那么就会形成一个新的组,现在有i个房子
于是dp[k-1][i-1][c_i-1]就转变为dp[k][i][ci]
如果ci == c_i-1, 就不会形成新的组,dp[k][i-1][c_i-1] 会变成 dp[k][i][ci]
那还要加上刷ci颜色的cost, 如果house已经有颜色了,不用刷,cost=0,
反之,house没有颜色,需要刷,则cost = cost[i][ci]
总结一下,状态转移为:
dp[k][i][ci] = min(dp[k][i][ci], dp[k - (ci != c_i-1)][i-1][c_i-1] + cost)
最后要返回的是最后一个房子在所有颜色中cost最小的那个,也就是min(dp[target][m])
可能还是比较难理解,在代码中再次给出注释
代码中要注意下标,题目中的房子,颜色都是从1开始的,而数组下标是从0开始。
public int minCost(int[] houses, int[][

该博客探讨了一种复杂的问题,即如何以最低成本将一排房子分为指定数量的邻里,每个邻里由相同颜色的房子组成。通过动态规划算法,我们可以找到使房子分为目标邻里数所需的最小成本。博客详细解释了状态转移方程,并提供了实现代码,包括剪枝技巧以优化解决方案。
最低0.47元/天 解锁文章
686

被折叠的 条评论
为什么被折叠?



