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

发布于:2024-06-29 ⋅ 阅读:(16) ⋅ 点赞:(0)

在这里插入图片描述

🚀 算法题 🚀

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

🚀 算法题 🚀

在这里插入图片描述
在这里插入图片描述

🚩 题目链接

⛲ 题目描述

给你两个长度为 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. 有了基本的思路,接下来我们就来通过代码来实现一下。
🥦 实现代码
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);
    }
}
🥦 运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


💬 共勉

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

在这里插入图片描述

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到