• 【图解 LeetCode 房屋染色 动态规划思想 + 代码实现】


    LeetCode 房屋染色 动态规划

    问题描述:

    假如有一排房子,共 n 个,每个房子可以被粉刷成 k 种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
    当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n*k 的矩阵来表示的。
    例如,costs[0][0] 表示第 0 号房子粉刷成 0 号颜色的成本花费;costs[1][2] 表示第 1 号房子粉刷成 2 号颜色的成本花费,以此类推。请你计算出粉刷完所有房子最少的花费成本。
    注意:
    所有花费均为正整数。

    输入输出示例:

    输入: [[1,5,3],[2,9,4]]
    输出: 5
    解释: 将 0 号房子粉刷成 0 号颜色,1 号房子粉刷成 2 号颜色。最少花费: 1 + 4 = 5;
    或者将 0 号房子粉刷成 2 号颜色,1 号房子粉刷成 0 号颜色。最少花费: 3 + 2 = 5.

    图解思路

    令dp[i][j]表示为第i- 1号房子染第j号颜色时的最小费用。

    image-20231025095052433
    image-20231114113039902

    代码实现

    public class Solution {
        /**
         * @param costs: n x k cost matrix
         * @return: an integer, the minimum cost to paint all houses
         */
        public int minCostII(int[][] costs) {
            int n = costs.length;
            if(n == 0)
                return 0;
            int k = costs[0].length;
            if(k == 0)
                return 0;
            
            //数组定义:dp[i][j] 表示的是 0 -> i - 1号房刷j种颜色的最小花费
            int dp[][] = new int[n + 1][k];
            int ans = Integer.MAX_VALUE;
            
            /**
            当且仅当最小值下标不等于j时,
            状态方程 dp[i][j] = min(dp[i - 1][0..k-1]) + cost[i - 1][j]
            **/
            
            for(int i = 1; i <= n; i++) {
                int firMin = Integer.MAX_VALUE, secMin = Integer.MAX_VALUE;
                int firIdx = 0, secIdx = 0;
                
                //寻找最小值和次小值以及他们的下标
                for(int j = 0; j < k; j++) {
                    if(dp[i - 1][j] < firMin) {
                        secMin = firMin;
                        secIdx = firIdx;
                        firMin = dp[i - 1][j];
                        firIdx = j;
                    } else if(dp[i - 1][j] < secMin) {
                        secMin = dp[i - 1][j];
                        secIdx = j;
                    }
                }
                
                for(int j = 0; j < k; j++) {
                	//因为相邻房屋不能涂相同颜色,所以当j等于最小值下标时要选择次小值
                    if(j != firIdx) {
                        dp[i][j] = firMin + costs[i - 1][j];
                    } else {
                        dp[i][j] = secMin + costs[i - 1][j];
                    }
                }
            }
            
            for(int i = 0; i < k; i++) {
                ans = Math.min(ans, dp[costs.length][i]);
            }
            
            return ans;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    谈谈我对服务网格的理解
    sql 常用命令-----增删查改
    详解Redis基础数据类型Set增删查(带Java源码)
    Vue虚拟DOM
    【七夕节】html+css+JavaScript+服务器 给女朋友的七夕过节网站
    【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【15】异步_线程池
    【面试题】如何去掉vue的url地址中的#号?及其原理?
    vue3使用router.push()页面跳转后,该页面不刷新问题
    机器人硬件在环仿真:解决实体开发与测试挑战,提升效率与安全性
    以前红火的农村大集,现在为何赶集的人越来越少,生意还好不好做
  • 原文地址:https://blog.csdn.net/weixin_45483322/article/details/134027825