leetcode每日一题:酿造药水需要的最少总时间

引言
今天的每日一题原题是2255. 统计是给定字符串前缀的字符串数目,直接模拟,逐个匹配words中的字符串是否是s的前缀即可。更换成前几天遇到的更有意思的一题来写这个每日一题。
题目
给你两个长度分别为 n 和 m 的整数数组 skill 和 mana 。
在一个实验室里,有 n 个巫师,他们必须按顺序酿造 m 个药水。每个药水的法力值为 mana[j],并且每个药水 必须 依次通过 所有 巫师处理,才能完成酿造。第 i 个巫师在第 j 个药水上处理需要的时间为 timeij = skill[i] * mana[j]。
由于酿造过程非常精细,药水在当前巫师完成工作后 必须 立即传递给下一个巫师并开始处理。这意味着时间必须保持 同步,确保每个巫师在药水到达时 马上 开始工作。
返回酿造所有药水所需的 最短 总时间。
示例 1:
输入: skill = [1,5,2,4], mana = [5,1,4,2]
输出: 110
解释:
| 药水编号 | 开始时间 | 巫师 0 完成时间 | 巫师 1 完成时间 | 巫师 2 完成时间 | 巫师 3 完成时间 |
|---|---|---|---|---|---|
| 0 | 0 | 5 | 30 | 40 | 60 |
| 1 | 52 | 53 | 58 | 60 | 64 |
| 2 | 54 | 58 | 78 | 86 | 102 |
| 3 | 86 | 88 | 98 | 102 | 110 |
举个例子,为什么巫师 0 不能在时间 t = 52 前开始处理第 1 个药水,假设巫师们在时间 t = 50 开始准备第 1 个药水。时间 t = 58 时,巫师 2 已经完成了第 1 个药水的处理,但巫师 3 直到时间 t = 60 仍在处理第 0 个药水,无法马上开始处理第 1个药水。
示例 2:
输入: skill = [1,1,1], mana = [1,1,1]
输出: 5
解释:
- 第 0 个药水的准备从时间
t = 0开始,并在时间t = 3完成。 - 第 1 个药水的准备从时间
t = 1开始,并在时间t = 4完成。 - 第 2 个药水的准备从时间
t = 2开始,并在时间t = 5完成。
示例 3:
输入: skill = [1,2,3,4], mana = [1,2]
输出: 21
提示:
n == skill.lengthm == mana.length1 <= n, m <= 50001 <= mana[i], skill[i] <= 5000
思路
首先要读懂题目,有个关键点是,对于同一瓶药水,在前一个巫师处理完成后,立即传递给下一个巫师进行处理。所以,这里跟直觉的贪心有一些区别,对于同一个巫师,处理一瓶药水后,并不能马上去处理下一瓶药水,要确保自己处理完成后,后一个巫师是空闲的状态。
读懂了这个点,我们来看第i瓶药水的处理,假设我们记第i瓶药水是从第beginDelay的时刻开始处理,而每个巫师处理上一瓶(第i-1瓶)药水的完成时间为end[],我们来看看这个beginDelay需要满足哪些条件:
- 对于第0个巫师,自己的开始处理时间是
beginDelay,必须晚于等于上一瓶结束时间,保证开始处理第i瓶是,自己是空闲的,即满足beginDelay >= end[0]; - 对于第1个巫师,自己的开始处理时间是
beginDelay + skill[i] * mana[0],必须晚于等于上一瓶结束时间,即满足beginDelay + skill[i] * mana[0] >= end[1]; - 对于第2个巫师,自己的开始处理时间是
beginDelay + skill[i] * (mana[0] + mana[1]),必须晚于等于上一瓶结束时间,即满足beginDelay + skill[i] * (mana[0] + mana[1]) >= end[1]; - 后面的巫师可以以此类推
这样,如果我们有n个巫师,对于第i瓶药水,就会有n个不等式,贪心的,求出满足这n个不等式的最小beginDelay,就可以求出对于第i瓶药水每个巫师的最早完成时间,用于列出第i+1瓶要求的不等式。特别的,对于第0瓶药水,当前每个巫师都是空闲的,可以认为end[]数组的值都是0。
另外,不等式中,我们对每瓶要求都会去求出mana[0]、mana[0] + mana[1]、mana[0] + mana[1] + mana[2] 这样的值,可以事先求一次前缀和,避免重复计算。
图解

代码

public long minTime(int[] skill, int[] mana) {
int n = skill.length;
int[] skillPreSum = new int[n + 1];
for (int i = 0; i < n; i++) {
skillPreSum[i + 1] = skillPreSum[i] + skill[i];
}
long[] end = new long[n];
for (int i = 0; i < mana.length; i++) {
long beginDelay = 0;
for (int j = 0; j < n; j++) {
beginDelay = Long.max(beginDelay, end[j] - (long)mana[i] * skillPreSum[j]);
}
for (int j = 0; j < n; j++) {
end[j] = beginDelay + (long)mana[i] * skillPreSum[j+1];
}
}
return end[n - 1];
}
耗时

leetcode每日一题:酿造药水需要的最少总时间的更多相关文章
- 【js】Leetcode每日一题-制作m束花所需的最少天数
[js]Leetcode每日一题-制作m束花所需的最少天数 [题目描述] 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k ...
- 【JavaScript】Leetcode每日一题-在D天内送包裹的能力
[JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...
- 【js】Leetcode每日一题-完成所有工作的最短时间
[js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...
- 【js】Leetcode每日一题-数组异或操作
[js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...
- 【js】Leetcode每日一题-解码异或后数组
[js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...
- 【JavaScript】Leetcode每日一题-青蛙过河
[JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...
- 【JavaScript】Leetcode每日一题-平方数之和
[JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...
- 【JavaScript】Leetcode每日一题-二叉搜索树的范围和
[JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...
- 【JavaScript】Leetcode每日一题-递增顺序搜索树
[JavaScript]Leetcode每日一题-递增顺序搜索树 [题目描述] 给你一棵二叉搜索树,请你 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没 ...
- 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素
[python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...
随机推荐
- 【事件分析】20250112-Usual 赎回机制调整事件
背景信息 https://docs.usual.money/ Usual 是一个聚合 RWA 的稳定币发行协议,经济模型中存在三种代币: USD0:Usual 发行的稳定币. USD0++:USD0+ ...
- 学Shiro完结版-2
第四章 INI配置--<跟我学Shiro> 之前章节我们已经接触过一些INI配置规则了,如果大家使用过如Spring之类的IoC/DI容器的话,Shiro提供的INI配置也是非常类似的,即 ...
- OV7670寄存器说明
I2C读出来的内容的地址,比datasheet给出的小9? add- 0x0 = 0x0add- 0x1 = 0x76add- 0x2 = 0x73add- 0x3 = 0x4add- 0x4 = 0 ...
- C#/.NET/.NET Core技术前沿周刊 | 第 22 期(2025年1.13-1.19)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...
- springboot logger 的配置
1.dev(开发环境)中logger配置详解 <!-- 文件输出格式 --> <property name="PATTERN" value="% ...
- Q:linux(群晖)修改网卡速率
问题:群晖速度莫名其妙变成了1MB/s左右,查看网络状态 网卡配置变成 全双工10Mb/s 解决方法 首先开启ssh登录权限 1.控制面板 – 终端机和SNMP里,开启SSH功能. 2.通过ssh连接 ...
- 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
在人工智能飞速发展的今天,大语言模型的应用越来越广泛.DeepSeek 作为近期爆火的一款大语言模型,受到了众多开发者的青睐. 今天这篇内容,就来聊聊,如何在本地自己的电脑上部署DeepSeek. 1 ...
- Spring默认BeanName
先说结论: 1.XML配置和注解生成默认BeanName的机制是不同的 2.XML配置默认BeanName = 全类名 + # + 数字,如 com.anyway.p2024.service.impl ...
- 关于DateTime的自定义转换
关于DateTime的自定义转换.把字符串时间转换成可以供DateTime类型识别的字符串类型的粗略实现. /// <summary> /// 把从数据库中读取的字符串的CurrentTi ...
- MES生产制造管理系统-BI看板 MES大屏看板
可视化看板最主要的目的是为了将生产状况透明化,让大家能够快速了解当前的生产状况以及进度,通过大数据汇总分析,为管理层做决策提供数据支撑,看板数据必须达到以下基本要求: 数据准确--真实反映生产情况 数 ...