【LeetCode:2742. 给墙壁刷油漆 + 递归 + 记忆化搜索 + dp】

|-----------|
| 🚀 算法题 🚀 |

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

|-----------|
| 🚀 算法题 🚀 |


🍔 目录

    • [🚩 题目链接](#🚩 题目链接)
    • [⛲ 题目描述](#⛲ 题目描述)
    • [🌟 求解思路&实现代码&运行结果](#🌟 求解思路&实现代码&运行结果)
      • [⚡ 递归 + 记忆化搜索 + dp](#⚡ 递归 + 记忆化搜索 + dp)
        • [🥦 求解思路](#🥦 求解思路)
        • [🥦 实现代码](#🥦 实现代码)
        • [🥦 运行结果](#🥦 运行结果)
    • [💬 共勉](#💬 共勉)

🚩 题目链接

⛲ 题目描述

给你两个长度为 n 下标从 0 开始的整数数组 cost 和 time ,分别表示给 n 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠:

  • 一位需要 付费 的油漆匠,刷第 i 堵墙需要花费 time[i] 单位的时间,开销为 cost[i] 单位的钱。
  • 一位 免费 的油漆匠,刷 任意 一堵墙的时间为 1 单位,开销为 0 。但是必须在付费油漆匠 工作 时,免费油漆匠才会工作。

请你返回刷完 n 堵墙最少开销为多少。

示例 1:

输入:cost = [1,2,3,2], time = [1,2,3,2]

输出:3

解释:下标为 0 和 1 的墙由付费油漆匠来刷,需要 3 单位时间。同时,免费油漆匠刷下标为 2 和 3 的墙,需要 2 单位时间,开销为 0 。总开销为 1 + 2 = 3 。

示例 2:

输入:cost = [2,3,4,2], time = [1,1,1,1]

输出:4

解释:下标为 0 和 3 的墙由付费油漆匠来刷,需要 2 单位时间。同时,免费油漆匠刷下标为 1 和 2 的墙,需要 2 单位时间,开销为 0 。总开销为 2 + 2 = 4 。

提示:

1 <= cost.length <= 500

cost.length == time.length

1 <= cost[i] <= 106

1 <= time[i] <= 500

🌟 求解思路&实现代码&运行结果


⚡ 递归 + 记忆化搜索 + dp

🥦 求解思路
  1. 思路1,设计一个三个参数的递归参数dfs(i,cnt,t)来返回最少开销。其中i表示当前来到的当前位置,cnt表示此时选择了多少个付费的工人,t表示付费工人的工作时间。遍历数组,每个位置可以选择或者不选。最终返回最小的开销。这样做,需要枚举的状态太多了,即使是缓存,也会超限,所以,需要继续优化。
  2. 思路2,在思路1的基础上,减少状态,dfs(i,t)来返回最少开销。i表示来到当前的位置,此时t表示后续还可以雇佣的免费工人,和思路1的区别在于,思路1的时间是只记录付费工人时间,思路2需要做的不仅仅是付费工人时间,免费工人也需要记录,实现时如果当前位置选,加当前位置的时间,如果不选,此时的位置需要交给免费工人来做,直接减1。最后,如果当前的 t > n - 1 - i,表示无需进行后续的过程,找到了一种开销。结果返回众多开销中最小的即可。
  3. 有了基本的思路,接下来我们就来通过代码来实现一下。
🥦 实现代码
java 复制代码
class Solution {
    int[] cost;
    int[] time;
    int[][] map;
    int n;

    public int paintWalls(int[] cost, int[] time) {
        this.cost = cost;
        this.time = time;
        this.n = cost.length;
        this.map = new int[n][n * 2 + 1];
        for (int i = 0; i < map.length; i++) {
            Arrays.fill(map[i], -1);
        }
        return dfs(0, 0);
    }

    private int dfs(int i, int t) {
        if (t > n - i - 1) {
            return 0;
        }
        if (i >= n) {
            return Integer.MAX_VALUE / 2;
        }
        int k = t + n;
        if (map[i][k] != -1) {
            return map[i][k];
        }
        int p1 = dfs(i + 1, t + time[i]);
        if (p1 != Integer.MAX_VALUE / 2) {
            p1 += cost[i];
        }
        int p2 = dfs(i + 1, t - 1);
        return map[i][k] = Math.min(p1, p2);
    }
}
🥦 运行结果

💬 共勉

|----------------------------------|
| 最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |

相关推荐
励志成为嵌入式工程师4 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
师太,答应老衲吧11 分钟前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
捕鲸叉34 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer39 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~1 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616881 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
wheeldown1 小时前
【数据结构】选择排序
数据结构·算法·排序算法
aloha_7892 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet