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

题目描述

这一类题目通常会问给定一组房子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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何评估CRM客户系统的功能是否满足助贷机构的需求?

评估 CRM 客户系统的功能是否满足助贷机构的需求&#xff0c;可以从以下几个方面入手&#xff1a; 1. 客户信息管理 - 检查系统能否全面、准确地记录客户的基本信息&#xff0c;如个人身份、财务状况、贷款需求等。 - 确认是否支持多维度的客户分类和标签功能&#xff0c;以…

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

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

css 流动边框

一、背景流动边框 实现原理&#xff1a; 用背景进行旋转&#xff0c;超出我们想显示的范围则hidden&#xff0c;就有以上的效果&#xff0c;可以用after或者before元素来实现也可以。 <!DOCTYPE html> <html lang"en"><head><meta charset&qu…

【开发环境】MacBook M2安装git并拉取gitlab项目,解决gitlab出现Access Token使用无效的方法

文章目录 安装Homebrew安装git打开IDEA配置git打开IDEA拉取项目 安装Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"在iTerm等命令行工具打开后&#xff0c;输入上面的命令 之后根据中文提示完成Homebrew的下载…

web项目打包成可以离线跑的exe软件

目录 引言打开PyCharm安装依赖创建 Web 应用运行应用程序打包成可执行文件结语注意事项 引言 在开发桌面应用程序时&#xff0c;我们经常需要将网页集成到应用程序中。Python 提供了多种方法来实现这一目标&#xff0c;其中 pywebview 是一个轻量级的库&#xff0c;它允许我们…

PyScript:在浏览器中释放Python的强大

PyScript&#xff1a;Python代码&#xff0c;直接在网页上运行。- 精选真开源&#xff0c;释放新价值。 概览 PyScript是一个创新的框架&#xff0c;它打破了传统编程环境的界限&#xff0c;允许开发者直接在浏览器中使用Python语言来创建丰富的网络应用。结合了HTML界面、Pyo…

把飞书云文档变成HTML邮件:问题挑战与解决历程

一、背景 云文档转HTML邮件 基于公司内部的飞书办公套件&#xff0c;早在去年6月&#xff0c;我们就建设了将飞书云文档转译成HTML邮件的能力&#xff0c;方便同学们在编写邮件文档和发送邮件时&#xff0c;都能有较好的体验和较高的效率。 当下问题 要被邮件客户端识别&am…

【蓝桥杯省赛真题46】python数字币统计 中小学青少年组蓝桥杯比赛 算法思维python编程省赛真题解析

目录 python数字币统计 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python数字币统计 第十四届蓝桥杯青少年组python比赛省赛真题 一、题目…

Spring Boot结合FFmpeg实现视频会议系统视频流处理与优化

在构建高效稳定的视频会议系统时,实时视频流的处理和优化是开发者面临的核心挑战之一。这不仅仅是简单的视频数据传输,更涉及到一系列复杂的技术问题,需要我们深入分析和有效解决。 高并发与实时性要求: 视频会议系统通常需要支持多人同时进行视频通话,这就意味着系统需要…

ONLYOFFICE8.1版本桌面编辑器——功能测评

一、编辑DOCX 相信大家都有写word文档的经历&#xff0c;不知道大家是不是跟我一样&#xff0c;感觉做一个word不难&#xff0c;但想做好一个word却很麻烦&#xff0c;功能太多&#xff0c;看的人眼花缭乱&#xff0c;有时候一个功能要找很久&#xff0c;甚至有的功能用一辈子都…

Matlab/simulink三段式距离/低阻抗保护

距离1段仿真波形如下所示 距离2段仿真波形如下所示 距离3段仿真波形如下所示

独立开发者系列(12)——下单与支付

做业务有个绕不开的业务逻辑&#xff0c;就是支付。这里总结一个基础的支付电商逻辑闭环流程&#xff0c;完成支付基础体系的实现。这里假定我们要实现的是一个独立的电商平台上允许用户在平台充值&#xff0c;其他的类似多多购物或者淘宝购物的流程逻辑。 数据表结构的逻辑设…

搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境(DAP-LINK: N32G45XVL-STB)

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP和KEIL产生测试项目 2.1 FSP生成项目 2.2 Keil中配置 3 硬件连接框图 4 一个测试案例 4.1 功能介绍 4.2 定时器函数 5 测试 搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境&#xff08…

【漏洞复现】I doc view——任意文件读取

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 I doc view 在线文档预览是一个用于查看、编辑、管理文档的工具…

LabVIEW材料样本结构缺陷检测

本文介绍了一种基于LabVIEW的实验室振动特性分析测试装置&#xff0c;通过分析振动特性来检测结构缺陷。文章详细描述了具体案例、硬件型号、工作原理、软件功能以及注意事项。 硬件型号 振动传感器&#xff1a;PCB Piezotronics 352C33加速度计 数据采集卡&#xff1a;NI PXI…

天气网站爬虫及可视化

摘要&#xff1a;随着互联网的快速发展&#xff0c;人们对天气信息的需求也越来越高。本论文基于Python语言&#xff0c;设计并实现了一个天气网站爬虫及可视化系统。该系统通过网络爬虫技术从多个天气网站上获取实时的天气数据&#xff0c;并将数据进行清洗和存储。同时&#…

Windows下activemq集群配置(broker-network)

1.activemq版本信息 activemq&#xff1a;apache-activemq-5.18.4 2.activemq架构 3.activemq集群配置 activemq集群配置基于Networks of Brokers 这种HA方案的优点&#xff1a;是占用的节点数更少(只需要2个节点),而且2个broker都可以响应消息的接收与发送。不足&#xff…

下载旧版本vscode及扩展,离线下载远程linux服务器插件

背景 工作的内网没有网络&#xff0c;无法使用网络来下载插件和vscode软件&#xff0c;且有远程linux服务器需求&#xff0c;linux服务器中lib相关库比较旧且无法更新&#xff0c;所以需要选择一个旧版本的vscode&#xff0c;相应插件也需要选择旧版本的 旧版本vscode下载 没…

JavaWeb——MySQL:事务的简单学习

前面学习完了数据库增删查改的SQL语言&#xff0c;约束&#xff0c;数据库设计&#xff0c;以及多表查询&#xff0c;再学完事务就达到初级工程师的水平了。 6. 事务 6.1 概念 事务类似于编程语言的方法&#xff0c;包含一组SQL指令。 事务是不可分割的&#xff1b; 该指令步…

高中数学:复数-三角表示式

一、定义 辐角主值 二、复数乘除运算的三角表示及其几何意义 乘法 复数乘法的几何意义 除法 练习 解