北滘企业网站开发,网站开发项目怎么接,企业网站数防泄露怎么做,网站开发的路径是什么题目描述与示例
题目描述
部门在进行需求开发时需要进行人力安排。当前部门需要完成 N 个需求#xff0c;需求用 requirements[i] 表示#xff0c;requirements[i] 表示第 i 个需求的工作量大小#xff0c;单位#xff1a;人月。这部分需求需要在 M 个月内完成开发#…题目描述与示例
题目描述
部门在进行需求开发时需要进行人力安排。当前部门需要完成 N 个需求需求用 requirements[i] 表示requirements[i] 表示第 i 个需求的工作量大小单位人月。这部分需求需要在 M 个月内完成开发进行人力安排后每个月的人力是固定的。
目前要求每个月最多有 2 个需求开发并且每个月需要完成的需求不能超过部门人力。请帮部门评估在满足需求开发进度的情况下每个月需要的最小人力是多少
输入描述
输入第一行为 M 第二行为 requirements 。
M 表示需要开发时间要求requirements 表示每个需求工作量大小
N 为 requirements 长度1 ≤ N / 2 ≤ M ≤ N ≤ 100001 ≤ requirements[i]≤ 10^9输出描述
对于每一组测试数据输出部门需要人力需求行末无多余的空格。
示例
输入
3
3 5 3 4输出
6说明
输入数据两行第一行输入数据 3 表示开发时间要求第二行输入数据表示需求工作量大小输出数据一行表示部门人力需求。
当选择人力为6时2个需求量为3的工作可以在1个月里完成其他2个工作各需要1个月完成。可以在3个月内完成所有需求。
当选择人力为5时4个工作各需要1个月完成一共需要4个月才能完成所有需求。
因此6是部门最小的人力需求。
解题思路
题目描述不是特别清晰只能通过示例进行反推。
考虑子问题在设置人力需求为**k**时需要多少个月能够完成所有工作。这个子问题与课上讲过的LeetCode881. 救生艇是完全一致的。
子问题中的人力需求k就等价于救生艇中的最大承重limit且每次选择都只能至多选择数组中的两个元素。该子问题使用排序双指针贪心的策略来完成其代码如下
def check(k, nums):left, right, ans 0, len(nums) - 1, 0while left right:if nums[left] nums[right] k:right - 1else:left 1right - 1ans 1return ans注意nums数组必须先排序才可以使用上述的贪心策略。
再得到check函数之后就需要找到一个适合的k了。显然k的取值是存在二段性的
当k很小时需要N个月才能完成工作即每一个月都只能完成1个工作当k很大时可以只花N/2个月就完成工作即每一个月都可以完成2个工作又因为N/2 ≤ M ≤ N成立故一定存在一个k恰好能够在M个月内完成工作
因此考虑二分查找完成本题。其主要代码如下
left, right max(nums), sum(nums) 1while left right:mid left (right - left) // 2if check(mid, nums) m:right midelse:left mid 1print(left)PS本题综合性比较强同时涉及了双指针贪心和二分查找还需要大家多加练习以将所有知识融会贯通。
代码
Python
# 题目【二分查找】2023C-部门人力分配
# 分值200
# 作者许老师-闭着眼睛学数理化
# 算法二分查找/贪心
# 代码看不懂的地方请直接在群上提问
# 相关题目LeetCode881.救生艇m int(input())
nums list(map(int, input().split()))
# 对nums数组进行排序方便后续每一次二分中的贪心过程
nums.sort()# 子问题
# 计算在人力需求为k时
# 需要最少多少个月才能完成所有需求nums
def check(k, nums):# 初始化left和right两个指针指向一头一尾初始化答案变量ansleft, right, ans 0, len(nums) - 1, 0# 进行循环退出循环条件为两指针相遇表示需求都完成while left right:# 如果两个工作所需人数超过了k# 则这个月只能完成需求人数多的工作nums[right]right左移if nums[left] nums[right] k:right - 1# 如果两个工作所需人数超过了k# 则这个月可以同时完成nums[left]和nums[right]这两个工作left右移、right左移else:left 1right - 1# 每轮匹配都会多一个月来工作更新ans变量ans 1return ans# 二分查找
# 设置做左闭右开区间
# 人力需求的最小值为nums数组中的最大值
# 否则max(nums)这个工作无法在一个月内完成
# 人力需求的最大值为nums数组中的两个最大元素相加
# 这里取一个更加宽松的上限sum(nums)考虑闭区间为sum(nums)1
left, right max(nums), sum(nums) 1# 进行二分
while left right:mid left (right - left) // 2# 如果在人力需求取mid时所花费时间不超过m# 那么说明人力需求还有富余right左移令搜索空间向左折半if check(mid, nums) m:right mid# 如果在人力需求取mid时所花费时间超过m# 那么说明人力需求有所紧缺left右移令搜索空间向右折半else:left mid 1# 退出二分查找时k right left是使得check(k, nums)恰好 ≤ m的第一个人力需求指
# 即为答案
print(left)Java
import java.util.*;public class Main {public static int check(int k, ListInteger nums) {int left 0, right nums.size() - 1, ans 0;while (left right) {if (nums.get(left) nums.get(right) k) {right--;} else {left;right--;}ans;}return ans;}public static void main(String[] args) {Scanner scanner new Scanner(System.in);int m scanner.nextInt();ListInteger nums new ArrayList();while (scanner.hasNextInt()) {nums.add(scanner.nextInt());}Collections.sort(nums);int left Collections.max(nums);int right nums.stream().mapToInt(Integer::intValue).sum() 1;while (left right) {int mid left (right - left) / 2;if (check(mid, nums) m) {right mid;} else {left mid 1;}}System.out.println(left);}
}C
#include iostream
#include vector
#include algorithm
#include numericusing namespace std;int check(int k, vectorint nums) {int left 0, right nums.size() - 1, ans 0;while (left right) {if (nums[left] nums[right] k) {right--;} else {left;right--;}ans;}return ans;
}int main() {int m;cin m;vectorint nums;int num;while (cin num) {nums.push_back(num);}sort(nums.begin(), nums.end());int left *max_element(nums.begin(), nums.end());int right accumulate(nums.begin(), nums.end(), 0) 1;while (left right) {int mid left (right - left) / 2;if (check(mid, nums) m) {right mid;} else {left mid 1;}}cout left endl;return 0;
}时空复杂度
时间复杂度O(N(logNlogU))。排序所需的时间复杂度为O(NlogN)。单次check()函数所需时间复杂度为O(N)二分查找的范围区间为U sum(nums) - max(nums)故总的二分查找所需时间复杂度为O(NlogU)
空间复杂度O(1)。忽略排序所需编译栈空间仅需若干常数变量。 华为OD算法/大厂面试高频题算法练习冲刺训练 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名目前已服务100同学成功上岸 课程讲师为全网50w粉丝编程博主吴师兄学算法 以及小红书头部编程博主闭着眼睛学数理化 每期人数维持在20人内保证能够最大限度地满足到每一个同学的需求达到和1v1同样的学习效果 60天陪伴式学习40直播课时300动画图解视频300LeetCode经典题200华为OD真题/大厂真题还有简历修改、模拟面试、专属HR对接将为你解锁 可上全网独家的欧弟OJ系统练习华子OD、大厂真题 可查看链接 大厂真题汇总 OD真题汇总(持续更新) 绿色聊天软件戳 od1336了解更多