华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
一个工厂有m条流水线,来并行完成n个独立的作业,该工厂设置了一个调度系统,在安排作业时,总是优先执行处理时间最短的作业。
现给定流水线个数m,需要完成的作业数n, 每个作业的处理时间分别为t1,t2…tn。请你编程计算处理完所有作业的耗时为多少?
当n>m时,首先处理时间短的m个作业进入流水线,其他的等待,当某个作业完成时,依次从剩余作业中取处理时间最短的进入处理。
输入描述
第一行为2个整数(采用空格分隔),分别表示流水线个数m和作业数n;
第二行输入n个整数(采用空格分隔),表示每个作业的处理时长t1,t2…tn。
0 < m,n < 100,0 < t1,t2…tn < 100。
注:保证输入都是合法的。
输出描述
输出处理完所有作业的总时长。
示例1
输入:
3 5
8 4 3 2 10
输出:
13
说明:
1、先安排时间为2、3、4的3个作业。
2、第一条流水线先完成作业,然后调度剩余时间最短的作业8。
3、第二条流水线完成作业,然后调度剩余时间最短的作业10。
4、总工耗时就是第二条流水线完成作业的时间13(3+10)。
题解
这道题目属于模拟调度的应用。我们需要按照作业的处理时间从短到长的顺序调度作业,并在有流水线空闲时立即分配下一个最短的作业。这确保了整体处理时间最短。
解题思路
- 排序作业时间:首先将所有作业按照处理时间从短到长排序,以便优先处理短作业。
- 初始化流水线:将前m个最短的作业分配给m条流水线。
- 模拟处理过程:使用一个队列来管理流水线的完成时间。每次从队列中取出最早完成的流水线,将下一个最短作业分配给它,并更新其完成时间(当前完成时间 + 新作业的处理时间)。
- 计算总耗时:最后一个完成的流水线的时间即为所有作业的总耗时。
时间复杂度
- 排序作业时间:O(n log n),其中n是作业数量。
- 调度过程:每个作业进出队列一次,每次操作O(1),总时间为O(n)。
- 总时间复杂度:O(n log n + n) = O(n log n)。
空间复杂度
- 存储作业时间:O(n)。
- 队列:O(m)。
- 总空间复杂度:O(n + m) = O(n)。
Python
"""
@author: code5bug
"""
from collections import deque
# 读取输入:流水线数量m和作业数量n
m, n = map(int, input().split())
# 读取每个作业的处理时间并排序
t = list(map(int, input().split()))
t.sort() # 升序排序,确保优先处理短作业
# 使用双端队列模拟流水线,存储每条流水线的完成时间
queue = deque()
# 初始化:将前m个最短作业分配给m条流水线
for i in range(min(m, n)):
queue.append(t[i])
idx = min(m, n) # 记录下一个待分配作业的索引
last_finish_time = 0 # 记录最后一个作业的完成时间
# 模拟作业调度过程
while queue:
# 取出最早完成的流水线
last_finish_time = queue.popleft()
# 如果还有未分配的作业
if idx < n:
# 将该流水线分配给下一个最短作业,并更新其完成时间
queue.append(last_finish_time + t[idx])
idx += 1
# 输出最后一个作业的完成时间,即总耗时
print(last_finish_time)
希望这个专栏能让您熟练掌握算法, 🎁🎁🎁 。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏