265 粉刷房子Ⅱ 易懂版本(python)

本文介绍了如何使用动态规划解决一个关于染色问题的算法,函数minCostII计算在给定成本矩阵中,以最少成本将每一天染成不同颜色的方案。通过状态转移和维护两个辅助数组minFirst和minSecond,逐步优化染色策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class Solution:
    def minCostII(self, costs: List[List[int]]) -> int:

        n,k = len(costs),len(costs[0])
        
        // f[i][j]表示 第i天染成第j中颜色的最小成本
        f = [[0] * k for _ in range(n+1)]
        
        // 分两种情况讨论,如果第i天要染的颜色和第i-1天最小成本对应的颜色不一样,那么f[i][j]只由上一天的最小成本对应颜色转移过来即可。
        // 然而如果第i天要染的颜色和第i-1天最小成本对应的颜色一样,那么第i天就不能由上一天的最小成本转移过来了,但次小成本可以,即我们需要维护上一天的最小成本及其对应的颜色和次小成本及其对应的颜色。

        // 首先初始化 两个数组, minFirst, minSecond,他们的元素分别对应最小成本和对应的颜色
        minFirst,minSecond = [inf,0],[inf,0]
        
        // 两次遍历确定 minFirst minSecond
        for i in range(k):
            f[1][i] = costs[0][i]
            if f[1][i] < minFirst[0]:
                minFirst = [f[1][i],i]

        for i in range(k):
            if minSecond[0] > f[1][i] >= minFirst[0] and i != minFirst[1]:
                minSecond = [f[1][i],i]

        for i in range(2,n+1):
            
            // 需要构造新的minFirst 和 minSecond,但过程中又要使用旧的minFirst和minSecond
            // 所以暂时用t_minFirst 和 t_minSecond 存储新的minFirst和minSecond
            t_minFirst = [inf,0]
            t_minSecond = [inf,0]

            // 下面的两个循环完成状态转移和新mF mS数组的构造
            for j in range(k):
                
                // 状态转移
                f[i][j] = minFirst[0] + costs[i-1][j] if minFirst[1] != j else minSecond[0] + costs[i-1][j]
                if f[i][j] < t_minFirst[0]:
                    t_minFirst = [f[i][j],j]

            for j in range(k):
                
                if t_minSecond[0] > f[i][j] >= t_minFirst[0] and j != t_minFirst[1]:
                    t_minSecond = [f[i][j],j]
            
            // 得到minFirst和minSecond 为下一天做准备
            minFirst = t_minFirst
            minSecond = t_minSecond

        return min(f[n])

这一题做完 256题也会做啦,当然也可以先做256再来思考这题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值