265. 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.
解释:
给了一个矩阵,要求从每一行中选择一个数,相邻两行不能选择相同的,求总和最小。 时间复杂度要求O(nk)
思考:
这个题相当于是之前那个偷或者不偷的升级版,难点就在于,之前那个题只需要考虑偷,这次对于每一个颜色的选择,都要进行比较。 总的状态转移方程是:对于第i个房子刷第j个颜色的最大收益为dp[i-1][j-1]=min(刨去dp[i-2][j-2]之后dp[i-2]的所有值) 所以其实可以对dp的每一行进行排序,然后在计算当前位置时,先比较最小值和当前颜色是否相同,如果相同则取次小值,如果不同则直接相加即可。 在最后一行找最小值即可实现总的最小。时间复杂度是nklogk 进一步优化可以发现,其实只需要记录当前这一行的最小值以及下标和次最小值即可,如果下一行和最小值同下标,则返回次小值;不然返回最小值即可。这样时间复杂度可以压缩为nk
答案:
class Solution:
def minCostII(self, costs: List[List[int]]) -> int:
if not costs:
return 0
dp = [[0 for i in range(len(costs[0]))] for j in range(len(costs))]
dp[0] = costs[0]
for i in range(1, len(costs)):
for j in range(len(costs[0])):
dp[i][j] = min(dp[i - 1][:j] + dp[i - 1][j + 1:]) + costs[i][j]
return min(dp[-1])