二分思想与相关问题(下)
接下来详细讲解几道比较难的例题,仔细体会二分和其他概念混合在一起的趣味。
下面这道题涉及了“碎片拼接”的概念,很妙,也很难想。
P r o b l e m 5 Problem5 Problem5 同时运行N台电脑的最长时间 LeetCode2141
你有 n
台电脑。给你整数 n
和一个下标从 0 开始的整数数组 batteries
,其中第 i
个电池可以让一台电脑 运行 batteries[i]
分钟。你想使用这些电池让 全部 n
台电脑 同时 运行。
一开始,你可以给每台电脑连接 至多一个电池 。然后在任意整数时刻,你都可以将一台电脑与它的电池断开连接,并连接另一个电池,你可以进行这个操作 任意次 。新连接的电池可以是一个全新的电池,也可以是别的电脑用过的电池。断开连接和连接新的电池不会花费任何时间。
注意,你不能给电池充电。
请你返回你可以让 n
台电脑同时运行的 最长 分钟数。
示例 1:
输入:n = 2, batteries = [3,3,3]
输出:4
解释:
一开始,将第一台电脑与电池 0 连接,第二台电脑与电池 1 连接。
2 分钟后,将第二台电脑与电池 1 断开连接,并连接电池 2 。注意,电池 0 还可以供电 1 分钟。
在第 3 分钟结尾,你需要将第一台电脑与电池 0 断开连接,然后连接电池 1 。
在第 4 分钟结尾,电池 1 也被耗尽,第一台电脑无法继续运行。
我们最多能同时让两台电脑同时运行 4 分钟,所以我们返回 4 。
示例 2:
输入:n = 2, batteries = [1,1,1,1]
输出:2
解释:
一开始,将第一台电脑与电池 0 连接,第二台电脑与电池 2 连接。
一分钟后,电池 0 和电池 2 同时耗尽,所以你需要将它们断开连接,并将电池 1 和第一台电脑连接,电池 3 和第二台电脑连接。
1 分钟后,电池 1 和电池 3 也耗尽了,所以两台电脑都无法继续运行。
我们最多能让两台电脑同时运行 2 分钟,所以我们返回 2 。
提示:
1 <= n <= batteries.length <= 10^5
1 <= batteries[i] <= 10^9
问题分析:
假设 N N N台电脑同时运行的时间的 t i m e time time,我们贪心地想,这个 t i m e time time越大,说明每台机器的耗电量越大,而电池的个数以及各自电量就那么点,就更容易把这些电池消耗完。也就是说,假设 N N N台电脑能够同时运行 t i m e time time时间,那么 N N N台电脑也一定能同时运行 t i m e − 1 time-1 time−1时间,反之则不一定同时运行 t i m e + 1 time+1 time+1时间。
所以我们可以得出 t i m e time time与 N N N台电脑能否同时运行 t i m e time time时间具体单调函数关系:
现在我们来讨论怎么解决
【问题5-1】给定整数 t i m e time time,返回 N N N台电脑能否同时运行 t i m e time time时间。
解决这个问题我们就要对电池的电量数组进行分析,如果某个电池的电量 e n e r g y > = t i m e energy >= time energy>=time,说明这个电池可以从0时刻开始就给某台电脑供电,直到 t i m e time time结束。我们称这种电池为”完美电池“,与之相对应的自然是碎片电池,碎片电池的电量 e n e r g y < t i m e energy < time energy<time。在整个分析过程中,我们可以把”完美电池单拎出来“,因为一个”完美电池“就可以完成一台电脑的供电,假设完美电池的个数为 m m m,那我们就只需要分析,在碎片电池组成的碎片电量数组条件下, N − m N-m N−m台电脑能否同时运行 t i m e time time时间。
这就涉及到**”碎片拼接“**问题了,我先给出结论:
【结论5-1】只要碎片数组的累加和 s u m > = t i m e ∗ ( N − m ) sum >= time*(N-m) sum>=time∗(N−m),那么这N-m台电脑就可以同时运行time时间。
我们拿电量数组 [ 7 , 6 , 5 , 7 , 8 , 9 ] [7,6,5,7,8,9] [7,6,5,7,8,9](对应着 A , B , C , D , E , F A,B,C,D,E,F A,B,C,D,E,F号电池)来给甲乙丙丁四台电脑供电同时运行 10 10 10分钟来举例子。
从甲开始,甲先用 A A A电池供 7 7 7分钟电,剩下三分钟由 B B B电池供,那我就用 B B B电池给乙供电,供3分钟以便留3分钟给甲,那乙还需要七分钟,我们用 C C C电池给乙供剩下来的七分钟里的5分钟,剩余2分钟换 D D D供,那丙我就用 D D D供五分钟,再用 E E E供五分钟,丁先用 E E E供一分钟,剩下九分钟全用 F F F供。文字描述有点冗杂,同学们看下面这张图吧。
“碎片拼接”的证明我稍后再讲,现在我们只需要再分析一下二分筛选条件,这道题目就可以解出来了。
t i m e time time非负,所以左边界 l e f t = 0 left = 0 left=0, N N N台电脑的最长运行时间数肯定小于各电池的电量和 s u m sum sum,所以右边界 l e f t = s u m left = sum left=sum。如果这 N N N台机器不能同时运行 m i d mid mid时间,则选取左半部分作为收敛区间 r i g h t = m i d − 1 right = mid -1 right=mid−1,如果这 N N N台机器可以同时运行 m i d mid mid时间,则选取右半部分作为收敛区间,并用 a n s w e r answer answer记录当前可行解 a n s w e r = m i d , l e f t = m i d + 1 answer = mid,left = mid+1 answer=mid,left=mid+1。
解决代码:
bool check(vector<int>& batteries, long time, int n) {long sum = 0;for (int i : batteries) {if (i >= time) { // 完美電池n--;if (n == 0)return true;} else {sum += i;}if (sum >= time * n)return true;}return false;
}long long maxRunTime(int n, vector<int>& batteries) {long left = 0;long All = 0;for (int i : batteries) {All += i;}long right = All;long long answer = 0;while (left <= right) {long mid = left + ((right - left) >> 1);if (check(batteries, mid, n)) {answer = mid;left = mid + 1;} else {right = mid - 1;}}return answer;
}
这个解法其实还可以利用贪心分析进行优化,同学们可以自己思考思考。
P r o b l e m 6 Problem6 Problem6 计算等位时间
描述:
给定一个数组 a r r arr arr长度为 n n n,表示 n n n个服务员,每服务一个顾客的时间。
给定一个正数 m m m,表示有 m m m个人等位,如果你是刚来的人,每个客人遵循有空位就上的原则,请问你需要等多久?假设 m m m远远大于 n n n,比如 n < = 1 0 3 n <=10^3 n<=103, m < = 1 0 9 m <= 10^9 m<=109,该怎么做是最优解?【谷歌一连考了好几个月,很经典的情景题】
问题分析:
我们记等待时间为 t i m e time time,如果 t i m e time time和某个变量具有函数单调性,那么就可以对 t i m e time time进行二分。经历前五道题的磨炼我们知道,“某个变量”一定要和题目中给的条件扯上关系。
根据题目条件,服务员的个数以及每个服务员服务客户的时间是固定的,也就是说,这家餐厅在单位时间内的客户接待量是固定的【我们假设服务场景发生的餐厅,这个假设无关紧要,只是方便大家去理解】,排在我前面的顾客数量 m m m越大,那我们就需要等待更多的时间,换而言之,
如果排在我前面的顾客数量为 m m m时,我们需要等待 t i m e 1 time_1 time1时间,那当排在我前面的顾客数量为 n , n < m n,n<m n,n<m时,我们需要等待的时间 t i m e 2 time_2 time2一定不会大于 t i m e 1 time_1 time1。
根据上面分析我们很容易想到二分筛选条件:如果 t i m e time time时间内餐厅接待的客人个数 > = m >=m >=m,说明等待时间可以提前结束,我们选取左半部分区间来进行区间收敛 a n s w e r = m i d , r i g h t = m i d − 1 answer = mid,right = mid-1 answer=mid,right=mid−1。如果 t i m e time time时间内餐厅接待的客人个数 < m <m <m,则说明在 t i m e time time时间过后仍有人在排队,我需要继续等待,所以我们选择右半部分区间来进行区间收敛 l e f t = m i d + 1 left = mid +1 left=mid+1。
现在我们只需要解决下面的问题就能进行二分搜索,
【问题6-1】给定时间 t i m e time time,请问餐厅在 t i m e time time时间内最多能接待多少个客人【接待指的是服务客人并结束服务, t i m e time time时刻还在接受服务的客人不参与计数】。
【问题6-1】利用贪心思想便可解决,要想服务的客人数量多,那服务员的工时就必须更长,我们就把服务员的工时拉满,全部工作 t i m e time time时间。最后只需要统计每个服务员工作 t i m e time time时间接待的顾客数,最后再求和即可。
在这里我给出【问题6-1】的解决代码:
bool check_Pro6(vector<int> arr, int time,int m) {int sum = 0;for (int i : arr) {sum += time / i;}if (sum >= m) return true;else return false;
}
二分筛选条件也讨论过,现在只差边界了,等待时间非负,所以左边界 l e f t = 0 left = 0 left=0,右边界可以这么去粗略确定,如果所有服务员的工作效率都和最慢的服务员一样,那么我需要等待的时间会比实际等待时间长很多,实际等待时间一定会小于 最低工作效率接待m个顾客所需要的时间。最低工作效率所需要的时间 对应着 a r r arr arr数组的最大值 m a x max max* ( m / n ) (m/n) (m/n)。
解决代码:
在这里只给出主体框架二分代码:
int solution_Pro6(vector<int> arr, int m) {int max = 0;for (int i : arr) {max = i > max ? i : max;}int left = 0;int right = max * (m / arr.size());int answer;while (left <= right) {int mid = (left + right) / 2;if (check_Pro6(arr, mid, m)) {answer = mid;right = mid - 1;}else {left = mid + 1;}}return answer;
}
相关文章:

二分思想与相关问题(下)
接下来详细讲解几道比较难的例题,仔细体会二分和其他概念混合在一起的趣味。 下面这道题涉及了“碎片拼接”的概念,很妙,也很难想。 P r o b l e m 5 Problem5 Problem5 同时运行N台电脑的最长时间 LeetCode2141 你有 n 台电脑。给你整数 n…...

【算法专题】搜索算法
二叉树剪枝 LCR 047. 二叉树剪枝 - 力扣(LeetCode) 本题要求我们将全部为0的二叉树去掉,也就是剪枝,当我们举一个具体的例子进行模拟时,会发现,只关注于对其中一个子树的根节点进行剪枝,由于我…...

B2064 斐波那契数列
题目描述 斐波那契数列是指这样的数列:数列的第一个和第二个数都为 11,接下来每个数都等于前面 22 个数之和。 给出一个正整数 aa,要求斐波那契数列中第 aa 个数是多少。 输入格式 第 11 行是测试数据的组数 nn,后面跟着 nn 行…...

Spark的介绍
一、分布式的思想 不管是数据也好,计算也好,都没有最大的电脑,而是多个小电脑组合而成。 存储:将3T的文件拆分成若干个小文件,例如每500M一个小文件,将这些小文件存储在不同的机器上 。 -- HDFS 计算&#…...

SpringBoot项目是如何启动
启动步骤 概念 运行main方法,初始化SpringApplication 从spring.factories读取listener ApplicationContentInitializer运行run方法读取环境变量,配置信息创建SpringApplication上下文预初始化上下文,将启动类作为配置类进行读取调用 refres…...

科技之光,照亮未来之路“2024南京国际人工智能展会”
全球科技产业的版图正以前所未有的速度重构,而位于中国东部沿海经济带的江浙沪地区,作为科技创新与产业升级的高地,始终站在这一浪潮的最前沿。2024年,这一区域的科技盛宴——“2024南京人工智能展会”即将在南京国际博览中心盛大…...

在深度学习计算机视觉的语义分割中,Boundary和Edge的区别是?
在深度学习中的计算机视觉任务中,语义分割中的 Boundary 和 Edge 其实有一些相似之处,但它们的定义和使用场景略有不同。下面是两者的区别: 1. Boundary(边界) 定义:Boundary 是指一个对象或区域的边界&a…...

【JAVA入门】Day41 - 字节缓冲流和字符缓冲流
【JAVA入门】Day41 - 字节缓冲流和字符缓冲流 文章目录 【JAVA入门】Day41 - 字节缓冲流和字符缓冲流一、缓冲流的体系结构二、字节缓冲流2.1 字节缓冲流提高效率的底层原理 三、字符缓冲流 在IO流体系中,FileInputStream,FileOutputStream,F…...

collocate join,bucket join,broadcast join,shuffle join对比分析
在分布式计算和大数据处理中,尤其是在使用像 Apache Spark、Hive 等大数据处理框架时,Join 操作是非常常见的。根据数据分布方式和执行机制,Join 操作可以分为不同的类型,如 Collocate Join、Bucket Join、Broadcast Join 和 Shuffle Join。以下是它们的详细对比分析: 1.…...

微信自动通过好友和自动拉人进群,微加机器人这个功能太好用了
又发现一个好用的功能,之前就想找一个这种工具,现在发现可以利用微加机器人的两个功能来实现,分别是加好友和关键词拉群 首先 微加机器人的专业版 > 功能 > 加好友设置 可以设置一个关键词通过,这样别人加好友的时候只需要输入制定内…...

R语言统计分析——功效分析3(相关、线性模型)
参考资料:R语言实战【第2版】 1、相关性 pwr.r.test()函数可以对相关性分析进行功效分析。格式如下: pwr.r.test(n, r, sig.level, power, alternative) 其中,n是观测数目,r是效应值(通过线性相关系数衡量࿰…...

Django创建模型
1、根据创建好应用模块 python manage.py startapp tests 2、在models文件里创建模型 from django.db import modelsfrom book.models import User# Create your models here. class Tests(models.Model):STATUS_CHOICES ((0, 启用),(1, 停用),# 更多状态...)add_time mode…...

盘点2024年大家都在用的短视频剪辑工具
你现在休息的时间是不是都靠短视频来消遣?看着看着你就会发现短视频制作好像我也可以了吧?这次我就介绍一些简单好操作的短视频剪辑工具。 1.FOXIT视频剪辑 连接直达>>https://www.pdf365.cn/foxitclip/ 短视频剪辑其实也不难,只需…...

“左侧文字横向”的QTabWidget
左侧用 QToolButton 组, 右侧用 QStackedWidget,信号槽绑定切换页面 可定制化高 QButtonGroup* btnGp new QButtonGroup(this);btnGp->addButton(ui->btn1, 0);btnGp->addButton(ui->btn2, 1);btnGp->addButton(ui->btn3, 2);connect…...

python学习之字符串操作
str python # 定义一个字符串变量 print(id(str))print(str) # 打印整个字符串 print(str[0:-1]) # 打印字符串第一个到倒数第二个字符(不包含倒数第一个字符) print(str[0]) # 打印字符串的第一个字符 print(str[2:5]) # 打印字符串第三到第…...

第7篇:【系统分析师】计算机网络
考点汇总 考点详情 1网络模型和协议:OSI/RM七层模型,网络标准和协议,TCP/IP协议族,端口 七层:应用层,表示层,会话层,传输层,网络层,数据链路层,…...

无人机培训机构组装调试技术详解
一、基础知识学习 在进入无人机组装调试领域之前,扎实的基础知识是不可或缺的。学员需掌握以下内容: 1. 无人机基本原理:了解无人机的飞行原理,包括升力、推力、重力和阻力等基本物理概念,以及无人机的飞行控制系统&…...

汽车的舒适进入功能是什么意思?
移动管家汽车的舒适进入系统是指无钥匙进入功能,它允许驾驶者在距离车辆一定范围内自动感应解锁车辆,并具备无钥匙启动功能。舒适进入系统的核心优势包括: 智能化操作:无需传统钥匙,通过智能感应实现车门解锁和…...

杂七杂八-系统环境安装
杂七杂八-系统&环境安装 1. 系统安装2. 环境安装 仅个人笔记使用,后续会根据自己遇到问题记录,感谢点赞关注 1. 系统安装 Windows安装linux子系统WSL2:使用windows系统跑linux程序(大模型)WSL VSCode:VSCode连接WSL实现高效…...

Redis高可用,Redis性能管理
文章目录 一,Redis高可用,Redis性能管理二,Redis持久化1.RDB持久化1.1触发条件(1)手动触发(2)自动触发 1.2 Redis 的 RDB 持久化配置1.3 RDB执行流程(1) 判断是否有其他持久化操作在执行(2) 父进…...

React项目中使用发布订阅模式
React项目中使用发布订阅模式 1.创建发布订阅器2.在组件中使用发布订阅器3. 订阅数据 发布订阅模式(也称观察者模式)是一种管理跨组件通信的有效方式,尤其是在不希望直接依赖于特定组件的情况下。这种模式允许一个对象(发布者&…...

buck boost Ldo 经典模型的默写
BUCK: BOOST: LDO: BUCK-BOOST:...

velero v1.14.1迁移kubernetes集群
1 概述 velero是vmware开源的一个备份和恢复工具,可作用于kubernetes集群下的任意对象和应用数据(PV上的数据)。github地址是https://github.com/vmware-tanzu/velero。 对于应用数据,可分文件级别的复制和块级别的复制。文件级…...

Qt Model/View之Model
在检查如何处理选择之前,您可能会发现检查模型/视图框架中使用的概念很有用。 基本概念 在模型/视图架构中,模型提供了一个标准接口,用于视图和委托访问数据。在Qt中,标准接口由QAbstractItemModel类定义。无论数据项如何存储在…...

如何在 Vue 3 中使用 Element Plus
在 Vue 3 中使用 Element Plus 是一个相对直接的过程,因为 Element Plus 是为 Vue 3 设计的 UI 组件库。以下是在 Vue 3 项目中集成和使用 Element Plus 的基本步骤: 1. 安装 Element Plus 首先,你需要在你的 Vue 3 项目中安装 Element Plu…...

【TVM 教程】在 Relay 中使用 Pipeline Executor
Apache TVM 是一个端到端的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 → Apache TVM 中文站tvm.hyper.ai/ 作者:Hua Jiang 本教程介绍如何将「Pipeline Executor」与 Relay 配合使用。 import tvm from t…...

使用mingw64 编译 QT开发流程
1. 安装QT5 QT5.12.12 安装时选择mingw的开发包 2. 使用qtdesigner 进行ui设计 生成ui文件 3. 将ui文件转换为.h 文件 uic mywindow.ui -o ui_mywindow.h代码中指向生成的 UI 对象的地方 要改成这个Form 4. 编译 创建mainwindow.cpp #include "mainwindow.h"…...

品读 Java 经典巨著《Effective Java》90条编程法则,第3条:用私有构造器或者枚举类型强化Singleton属性
《Effective Java》中的第3条编程法则主要是针对在开发过程如何实现单例模式,作者 Joshua Bloch 在书中给出了3种单例模式的实现方式:私有构造器和公有静态域、私有构造器和公有静态方法、枚举式。 什么是单例模式? 单例模式是一种设计模式…...

如何在Flask中处理表单数据
在Flask中处理表单数据是一个常见的任务,它涉及从客户端接收数据并在服务器端进行解析和处理。Flask本身不直接提供表单验证的功能,但它可以与WTForms等库结合使用来简化表单处理过程。不过,即使没有WTForms,你仍然可以直接通过Fl…...

9月12日的学习
练习 #include "widget.h" #include "ui_widget.h" QListWidgetItem *p; Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),socket(new QTcpSocket(this))//给客户端指针实例化空间及关联父组件 {ui->setupUi(this);//初始化,ui-…...