当前位置: 首页 > article >正文

LeetCode:3376. 破解锁的最少时间 I(DFS回溯 Java)

目录

3376. 破解锁的最少时间 I

题目描述:

实现代码与解析:

DFS

原理思路:


3376. 破解锁的最少时间 I

题目描述:

Bob 被困在了一个地窖里,他需要破解 n 个锁才能逃出地窖,每一个锁都需要一定的 能量 才能打开。每一个锁需要的能量存放在一个数组 strength 里,其中 strength[i] 表示打开第 i 个锁需要的能量。

Bob 有一把剑,它具备以下的特征:

  • 一开始剑的能量为 0 。
  • 剑的能量增加因子 X 一开始的值为 1 。
  • 每分钟,剑的能量都会增加当前的 X 值。
  • 打开第 i 把锁,剑的能量需要到达 至少 strength[i] 。
  • 打开一把锁以后,剑的能量会变回 0 ,X 的值会增加一个给定的值 K 。

你的任务是打开所有 n 把锁并逃出地窖,请你求出需要的 最少 分钟数。

请你返回 Bob 打开所有 n 把锁需要的 最少 时间。

示例 1:

输入:strength = [3,4,1], K = 1

输出:4

解释:

时间能量X操作更新后的 X
001什么也不做1
111打开第 3 把锁2
222什么也不做2
342打开第 2 把锁3
433打开第 1 把锁3

无法用少于 4 分钟打开所有的锁,所以答案为 4 。

示例 2:

输入:strength = [2,5,4], K = 2

输出:5

解释:

时间能量X操作更新后的 X
001什么也不做1
111什么也不做1
221打开第 1 把锁3
333什么也不做3
463打开第 2 把锁5
555打开第 3 把锁7

无法用少于 5 分钟打开所有的锁,所以答案为 5 。

提示:

  • n == strength.length
  • 1 <= n <= 8
  • 1 <= K <= 10
  • 1 <= strength[i] <= 106

实现代码与解析:

DFS

class Solution {
    public int findMinimumTime(List<Integer> strength, int k) {
        
        dfs(0, 0, strength.toArray(new Integer[strength.size()]), k);
        return res;
    }

    int res = 0x3f3f3f3f;

    private void dfs(int cnt, int cur, Integer[] strength, int k) {
        if (cur >= res) {
            return;
        }
        if (cnt == strength.length) {
            res = cur;
            return;
        }

        int x = 1 + k * cnt;
        for (int i = 0; i < strength.length; i++) {
            if (strength[i] == -1) continue;
            int tmp = strength[i];
            strength[i] = -1;
            dfs(cnt + 1, cur + (tmp - 1) / x + 1, strength, k);
            strength[i] = tmp;
        }

    }
}

原理思路:

        dfs全排列遍历。

  • cnt:已处理锁的序号(从 0 起),据此知晓当前开锁阶段,也能算能量增加因子。
  • cur:当前累计时间。
  • strength:存各锁所需能量值的数组,递归中通过标记元素,设为 -1表示锁是否已处理。
  • k:与剑能量增加因子变化规则相关,开锁后按其增加,用于准确算剑能量增长情况。

递归边界条件及剪枝操作:

  • if (cur >= res) 是剪枝判断,若当前累计时间大于等于已找到的最少时间,当前开锁策略不优,直接返回,避免多余搜索分支。
  • if (cnt == strength.length) 是终止条件,处理完所有锁,若 cur 小于 res(即更优),将 cur 更新给 res 后返回。

核心递归逻辑及操作:

  • 先算 x = 1 + k * cntx 为当前剑能量增加因子,初始值 1(cnt = 0 时),开锁后按 k 增加,用于算积攒能量开下锁的时间。
  • for 循环遍历 strength 数组:
    • if (strength[i] == -1) 跳过已标记 -1 的元素,意味着已处理过。
    • int tmp = strength[i]; 保存当前锁能量值,方便后续操作与恢复。
    • strength[i] = -1; 标记当前锁已处理。
    • dfs(cnt + 1, cur + (tmp - 1) / x + 1, strength, k); 核心递归,处理下锁,更新 cur(tmp - 1) / x + 1 算开当前锁额外花费等待时间,向上取整,继续下一层递归。
    • strength[i] = tmp; 递归结束后恢复元素值,便于回溯尝试其他开锁顺序。

http://www.kler.cn/a/443396.html

相关文章:

  • 二十三种设计模式-原型模式
  • STM32Flash读写BUG,坑—————4字对齐
  • 深度学习:探索人工智能的未来
  • 前后端分离架构设计与实现:构建现代Web应用的基石
  • vulnhub靶场-potato(至获取shell)
  • 基于Informer网络实现电力负荷时序预测——cross validation交叉验证与Hyperopt超参数调优
  • uboot 打开log 的 方法
  • 题海拾贝:P8772 [蓝桥杯 2022 省 A] 求和
  • 在Visual Studio Code (VSCode) 中将终端输出重定向到一个文本文件中
  • 如何在Playwright中操作窗口的变化
  • 【SH】Ubuntu Server 24搭建Web服务器访问Python程序研发笔记
  • 在Rocky Linux中安装【Jenkins】的详细指南
  • Python MySQL 进阶用法详解
  • TRELLIS,一键生成3D模型,图像转3D,微软开源
  • MYSQL语法
  • 【人工智能】从TF-IDF到BERT:Python实现文本分类的全面指南
  • 12.7深度学习_经典神经网络_VGG
  • 八、Hbase
  • 数字设计工程师学习路线:从基础到高阶的全面指南
  • 什么,不用 Tomcat 也能运行 Java web?
  • 4.redis通用命令
  • API超越应用的时代,深入了解F5 API安全解决方案
  • 接口文档案例
  • 以太网帧、IP数据报图解
  • 【机器学习】机器学习的基本分类-强化学习-策略梯度(Policy Gradient,PG)
  • 在Ubuntu中配置mysql,并允许外部访问数据库