数组划分k份:二分法

给定一个正数数组arr和工人数num,目标是将数组尽可能均匀地划分为k份,每份的元素之和不超过一个工人能完成的工作量。通过二分查找找到使所有工作恰好由k个工人完成的工人最大工作时长limit。测试用例展示了不同情况下的解决方案。关键在于找到使数组划分满足条件的limit。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

给定一个整型数组arr, 数组中的每个值都为正数,表示完成一个工作需要的时间,再给定一个整数num,表示工人的数量,每个工人只能完成连在一起的工作。所有工人并行工作,请返回完成所有的工作的最少时间。

本题的问题可以理解为给定一个数组arr[] 将其尽可能的等分为k份,其中每一份中的最大值的最小值是多少?

测试用例

输入
3 2
3 1 4
输出
4
说明: 划分为[3 1]、[4]

输入
5 3
1 1 1 4 3
输出
4
说明:划分为[1 1 1]、[4]、[3]

本题思路

最终所求是完成工作最多的那个工人的工作时长,问题需要使得这个时长尽可能小,即数组尽可能的均匀分配

设定每个工人的工作时长限制为limit 如果limit=sum 那么只需要一个工人就可以完成所有工作 如果limit=0 那么无法完成

因此可以划分为一个二分的思路,即存在这样一个人均工作时长(均分每部分的上限),使得完成arr[]所有工作,恰好k个工人能完成,这里恰好的意思是:即不会出现工人空闲的情况(之前人完成了),也不会出现后面部分工作没有完成(每个人工作量太小)。

关键函数

该函数返回每个人工作上限limit 完成所有工作需要的工人数量

int get_min(vector<long long>& arr,long long limit)  //每个人工作时长不超过limit 完成arr 至少需要多少人
{
   
   
    int len=arr.size();
    int count=</
这段代码是一个解决“最大化甜度”问题的算法,目标是在将巧克力棒分成K+1的情况下,使得最小的那一块巧克力棒的甜度尽可能大。我们通过二分查找的方式来寻找最优解。 ### 代码功能分解 #### 主函数 `maximizeSweetness` ```python def maximizeSweetness(self, sweetness, K): ``` **输入参数说明:** - `sweetness`: 表示每一块巧克力的小段甜度值组成的数组。 - `K`: 需要分割成的部分数减一(即需要切 K 刀形成 K+1 块)。 **核心思想:** 通过二分法确定可以分配给每个人的最大甜度,并找到满足条件下的最大值。 **步骤解析:** 1. **初始化左右边界`left` 和 `right`** - 将左边界设置为0 (`left = 0`),右边界初始设为所有甜度之和(`sum(sweetness)`). 2. **二分搜索过程** ```python while left + 1 < right: mid = (left + right) // 2 if self.check(sweetness, mid, K): left = mid else: right = mid ``` 这部分实现了经典的二分查找: - 计算中间值 `mid`, 即当前尝试作为结果的一个潜在答案; - 调用辅助检查函数 `check()` 来验证是否可以在保证每一小块都大于等于 `mid` 的前提下完成切割任务; 如果可行,则更新左侧界线到 `mid`; 否则缩小右侧界限至 `mid`. 3. **最终确认并返回结果** 最后一步判断当采用最接近的理想值(right)时是否会成功;如果能够达成就选择较大的那个数值(right),否则默认取较小者(left)。 --- #### 辅助函数 `check()` ```python def check(self, sweetness, mid, K): ``` 该函数用于测试对于某个特定的目标值(mid), 是否有可能按照要求去划分原始数据集. **内部实现细节:** - 创建了一个空列表变量bars存储已形成的符合条件的大块. - 初始化一个临时累积量now_sweet记录从当前位置开始连续累加直到达到或超过"候选标准"(mid). 每当遇到一个新的足够大的片段时(即now_sweet >= mid 并且还没有超出允许的数量限制[K]), 它会被计入有效条目内并将计数清零准备计算下一个可能的大块. 最后有几种情况可能导致失败标志返回false: - 当前剩余未处理的数据不足以构成另一个新的合格单元; - 或者虽然理论上还存在一些额外材料但实际操作上无法再生成更多独立单位因为已经达到了指定数目上限K; 只有完全满足上述两方面约束条件下才会判定此试探性的阈值有效并且给出肯定答复true.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值