[Leetcode刷题] - 栅栏涂漆DP类问题

news2024/10/6 2:28:45

题目描述

这一类题目通常会问给定一组房子n和一组染料k去涂漆,并且会加入限制条件比如:某种颜色只能使用1次,相相邻房子不能涂同一种颜色,或者最多不能超过连续3个房子涂想通过颜色等等,让我们列举所有可能性总和,带限制条件的排列组合类问题。

题目链接

求方案数

Leetcode 256 - Paint HouseLevel up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.icon-default.png?t=N7T8https://leetcode.com/problems/paint-house/description/

Leetcode 265 - Paint House IILevel up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.icon-default.png?t=N7T8https://leetcode.com/problems/paint-house-ii/

Leetcode 276 - Paint FenceLevel up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.icon-default.png?t=N7T8https://leetcode.com/problems/paint-fence/

盖楼问题Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.icon-default.png?t=N7T8https://leetcode.com/discuss/interview-question/1400517/UBER-OA-QUESTION-HELP-NEEDED/1104017

题目思路

问题1: 给n座房子涂漆,有k个颜色,限制条件是相邻两个房子不能涂相同颜色,求总方案数

Leetcode 256 - Paint House,Leetcode 265 - Paint House II

思路1 - 暴力搜索DFS

对于排列组合类问题,最直观的思路就是DFS暴力枚举出所有解,每一次递归我们枚举所有的颜色,跳过和当前相同颜色,然后选取剩下k-1种颜色继续计算。

代码如下:

class Solution {
    int min = Integer.MAX_VALUE;
    int[][] arr;
    public int minCost(int[][] costs) {
        arr = costs;
        dfs(0, -1, 0);
        return min;
    }

    private void dfs(int idx, int opt, int cost) {
        if (idx==arr.length) {
            min = Math.min(cost, min);
            return;
        }

        for (int i=0; i<arr[idx].length; i++) {
            if (i==opt) continue; // cannot paint same color for adjant
            dfs(idx+1, i, cost+arr[idx][i]);
        }
    }
}

时间复杂度:O((k-1)^N),每一次选择都有k-1个颜色可选;空间复杂度:O(1),抛去递归占用的额外栈空间。 

思路1优化 - DFS记忆化搜索

不难看出,在递归的过程中,存在着很多局部组合是重复的,我们完全可以将这些重复组合缓存起来,从而实现优化剪枝。

为了实现记忆化搜索我们需要改写思路1代码,舍弃全局最小值,而是在递归中不断更新局部最小值, 之前的思路1的代码,我们是向下递归,在到底后更新结果,这样很难缓存重复解。可以将思路1的想法改写成,向下递归,在每一层递归时计算最优解。

改写代码如下:

class Solution {
    int[][] arr;
    public int minCost(int[][] costs) {
        arr = costs;
        int[][] dp = new int[costs.length][costs[0].length+1];
        for (int i=0; i<costs.length; i++) {
            Arrays.fill(dp[i], -1);
        }

        return dfs(0, 0, dp);
    }

    private int dfs(int idx, int opt, int[][] dp) {
        if (idx==arr.length) {
            return 0;
        }

        if (dp[idx][opt]!=-1) return dp[idx][opt];

        int res = Integer.MAX_VALUE;
        for (int i=1; i<=arr[idx].length; i++) {
            if (i==opt) continue; //cannot paint same color for adjant
            res = Math.min(arr[idx][i-1] + dfs(idx+1, i, dp), res);
        }

        return dp[idx][opt] = res;
    }
}

时间复杂度:记忆化后的时间复杂度不太好计算,大大小于O((k-1)^N);空间复杂度:O(NK),开额外空间保存记忆化结果。 

思路2 - 动态规划

记忆化搜索其实就是自上而下的动态规划实现,我们只需要把递归逻辑转化为迭代即可。首先初始化状态 dp[i][j] 定义为从0到i个房子,在第i个房子涂j个染料时当前的最小cost。

状态转移方程为:

dp[i][j] = costs[i][j] + min_{x\epsilon {1, k}}(dp[i-1][x])

代码如下:

class Solution {
    public int minCost(int[][] costs) {
        int[][] dp = new int[costs.length][costs[0].length]; // [0, i] i 处涂 k的最小cost
        for (int i=0; i<costs[0].length; i++) {
            dp[0][i] = costs[0][i];
        }

        for (int i=1; i<costs.length; i++) {
            for (int k=0; k<costs[i].length; k++) {
                int res = Integer.MAX_VALUE;
                for (int j=0; j<costs[i].length; j++) {
                    if (j==k) continue;
                    res = Math.min(res, dp[i-1][j]);
                }
                dp[i][k] = costs[i][k] + res;
            }
        }

        int min = Integer.MAX_VALUE;
        for (int i: dp[costs.length-1]) {
            min = Math.min(min, i);
        }
        return min;
    }

}

时间复杂度:O(Nk^2);空间复杂度:O(Nk)。 

问题2: 给n座房子涂漆,有k个颜色,限制条件不能给连续超过2座房子涂相同颜色,求总方案数

Leetcode 276 - Paint Fence

思路1 - 暴力搜索DFS

思路1优化 - DFS记忆化搜索

思路2 - 动态规划

问题3: 给n座房子涂漆,有k种颜色,限制条件1不能给连续超过2座房子涂相同颜色,限制条件2某种颜色最多只能用m次,求总方案数

盖楼问题

思路1 - 暴力搜索DFS

思路1优化 - DFS记忆化搜索

代码如下:

private int dfs(int n, int i, int r, int co, int[][][] dp) {
    if (i==n) return 1;

    int ans = 0;
    if (r==0) ans+=dfs(n, i+1, 1, 0, dp);

    if (dp[i][r][co]!=-1) return dp[i][r][co];

    // 设置为apt
    ans+=dfs(n, i+1, r, 0, dp);

    if (co<=1) {
        //连续有2个那么还可以建office
        ans+=dfs(n, i+1, r, co+1, dp);
    }

    return dp[i][r][co] = ans;
}

思路2 - 动态规划

代码如下:

private int dyp(int n) {
    int[][][] dp = new int[n][2][3]; // n j k -> k 表示当前连续了几个如果当前为不选office, k=0

    dp[0][0][0] = 1; // apt
    dp[0][1][0] = 1; // cafe
    dp[0][0][1] = 1; // office

    for (int i=1; i<n; i++) {
        // for rest
        for (int j=0; j<3; j++) {
            dp[i][1][0]+=dp[i-1][0][j];
        }

        // for office
        for (int j=1; j<3; j++) {
            dp[i][0][j]+=dp[i-1][0][j-1];
            dp[i][1][j]+=dp[i-1][0][j-1];
        }

        // for apt
        for (int j=0; j<3; j++) {
            dp[i][0][0]+=dp[i-1][0][j];
            dp[i][1][0]+=dp[i-1][1][j];
        }

    }

    int sum = 0;
    for (int j=0; j<3; j++) {
        sum+=dp[n-1][0][j];
        sum+=dp[n-1][1][j];
    }

    return sum;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1875383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企智汇PaaS平台:数字化时代下的项目管理利器

企智汇项目管理系统PaaS平台是一个强大而灵活的平台&#xff0c;旨在为企业提供高效、智能的项目管理解决方案。在项目管理领域提供了显著的优势&#xff0c;这些优势主要体现在以下几个方面&#xff1a; 1.快速部署与迭代&#xff1a;企智汇一体化PaaS平台提供了预配置的基础…

代理IP如何助力旅游信息聚合?

在数字化时代&#xff0c;旅游信息聚合对于提升服务质量、优化用户体验起着至关重要的作用。随着在线旅游预订的普及&#xff0c;旅游信息的采集、整合和呈现成为了一个复杂而关键的过程。在这个过程中&#xff0c;代理IP技术以其独特的优势&#xff0c;为旅游信息聚合提供了强…

STM32介绍和资料地址

STM32标准外设软件库 https://www.st.com.cn/zh/embedded-software/stm32-standard-peripheral-libraries.html 支持标准外设库的产品系列&#xff1a;

ROS2开发机器人移动

.创建功能包和节点 这里我们设计两个节点 example_interfaces_robot_01&#xff0c;机器人节点&#xff0c;对外提供控制机器人移动服务并发布机器人的状态。 example_interfaces_control_01&#xff0c;控制节点&#xff0c;发送机器人移动请求&#xff0c;订阅机器人状态话题…

【升压电子烟方案】DC-DC电源升压恒压芯片FP6277+全极低功耗霍尔MH251在电子烟中的应用

电子烟是一种新型烟草制品&#xff0c;由于其健康、环保和口感多样化的特点&#xff0c;逐渐受到了消费者的青睐。 升压芯片作为电子烟的核心组件之一&#xff0c;主要作用是将输入的电压升高至合适的工作电压&#xff0c;霍尔传感器控制电子烟的使用状态&#xff0c;以确保电子…

【笔记】Spring Cloud Gateway 实现 gRPC 代理

Spring Cloud Gateway 在 3.1.x 版本中增加了针对 gRPC 的网关代理功能支持,本片文章描述一下如何实现相关支持.本文主要基于 Spring Cloud Gateway 的 官方文档 进行一个实践练习。有兴趣的可以翻看官方文档。 由于 Grpc 是基于 HTTP2 协议进行传输的&#xff0c;因此 Srping …

已解决java.security.acl.LastOwnerException:无法移除最后一个所有者的正确解决方法,亲测有效!!!

已解决java.security.acl.LastOwnerException&#xff1a;无法移除最后一个所有者的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 1. 检查当前所有者数量 2. 添加新的所有者 3. 维…

【Python系列】Python 中循环依赖问题及其解决方案

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

CAN和CANFD数据写入.asc文件的dll

因为工作需要&#xff0c;需要做一些硬件不是CANoe的上位机&#xff08;比如说周立功CAN,NI-CAN&#xff09;&#xff0c;上位机需要有记录数据的功能&#xff0c;所以用Qt制作了一个记录数据的dll&#xff0c;方便重复使用&#xff08;因为有的客户指定了编程软件&#xff0c;…

Spring框架整体概念

Spring框架基础概念 首先&#xff0c; 从Spring框架的整体架构和组成对整体框架有个认知。 Spring基础 - Spring和Spring框架组成 上图是从官网4.2.x获取的原图&#xff0c;目前我们使用最广法的版本应该都是5.x&#xff0c;5版本移除了Web模块中的Portlet子模块&#xff0c;新…

机器人控制系列教程之控制理论概述

经典控制理论 经典控制理论主要研究线性定常系统。所谓线性控制系统是指系统中各组成环节或元件的状态由线性微分方程描述的控制系统。如果描述该线性系统的微分方程系数是常数,则称为线性定常系统。描述自动控制系统输入量、输出量和内部量之间关系的数学表达式称为系统的数学…

STM32第七课:KQM6600空气质量传感器

文章目录 需求一、KQM6600模块及接线方法二、模块配置流程1.环境2.配置时钟和IO3.配置串口初始化&#xff0c;使能以及中断4.中断函数 三、数据处理四、关键代码总结 需求 能够在串口实时显示当前的VOC&#xff08;挥发性有机化合物&#xff09;&#xff0c;甲醛和Co2浓度。 …

GPU算力是什么,哪些行业需要用到GPU算力?

近两年&#xff0c;计算能力已成为推动各行各业发展的关键因素。而GPU&#xff08;图形处理器&#xff09;算力&#xff0c;作为现代计算技术的重要分支&#xff0c;正逐渐在多个领域展现出其强大的潜力和价值。尚云将简要介绍GPU算力的定义和基本原理&#xff0c;并探讨其在哪…

使用Apache POI库在Java中导出Excel文件的详细步骤

使用Apache POI库在Java中导出Excel文件的详细步骤 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技…

企业中对RAG的优化方案

企业中对RAG的优化方案 RAG优化&#xff1a;检索、语义和生成方面的提升RAG流程一、数据处理优化数据清洗实际案例 二、检索方面优化向量库检索倒排索引数据库检索 三、生成方面优化调整Prompt 四、架构优化RAGAgent架构Self-RAG架构Agentic RAG架构 总结 RAG优化&#xff1a;检…

【Django】网上蛋糕项目商城-热销和新品

概念 本文将完成实现项目的热销和新品两个分类的商品列表进行分页展示。 热销和新品功能实现步骤 在head.html头部页面中点击这两个超链接向服务器发送请求。 在urls.py文件中定义该请求地址 path(goodsrecommend_list/,views.goodsrecommend_list) 在views.py文件中定义g…

mac配置hdc

首先需要找到 .zshrc 文件&#xff1a; 访达进入到user文件夹中&#xff0c;shiftcommand.键显示隐藏文件&#xff1a; 双击打开进行编辑&#xff0c;在最后添加 //HDC_HOME 指的是hdc的绝对路径&#xff0c;要替换成自己的路径 export HDC_HOME/Users/你的名字/Library/Huaw…

系统架构设计师 - 计算机网络(1)

计算机网络 计算机网络TCP/IP 协议簇TCP与UDP ★★★DHCP与DNS ★★★DNS 协议应用DHCP 协议应用 网络规划与设计逻辑设计与物理设计 ★★★★逻辑网络设计物理网路设计 层次化网络设计网络冗余设计 网络存储 ★★网络存储方式磁盘阵列 - Raid 大家好呀&#xff01;我是小笙&am…

二刷算法训练营Day45 | 动态规划(7/17)

目录 详细布置&#xff1a; 1. 139. 单词拆分 2. 多重背包理论基础 3. 背包总结 3.1 背包递推公式 3.2 遍历顺序 01背包 完全背包 详细布置&#xff1a; 1. 139. 单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单…

北大西洋横断面(ANT)项目计划

North Atlantic Transect (ANT) program 简介 - **&#x1f5fa;️ 北大西洋横断面计划 (ANT) 概述** 北大西洋横断面计划 (ANT) 是一个由美国资助的 GEOTRACES 项目&#xff0c;旨在测量非洲海岸沿线的海洋化学参数。该计划收集了有关海水中的溶解氧、营养盐、碳酸盐离子、微…