问题描述
小C、小U、小R是工厂里的三个工人,他们互相协同制作零件。零件的制作包括三种工序:"加工"、"质检"、"收尾",分别由小C、小U、小R负责。每个零件需要多次进行"加工"和"质检"工序,但只需要进行一次"收尾"工序。每次"加工"完成后,需要进行对应的"质检",只有当质检合格后,才可以开始下一次"加工"。当所有的"加工"和"质检"工序完成后,进行一次"收尾"工序,这样零件制作就算完成了。
小C、小U、小R的工作方式原本非常机械化,他们只能按照既定顺序一个工序一个工序地完成一个零件,比如对于一个零件的工序"加工1、质检1、加工2、质检2、收尾",他们会按顺序逐一完成各自的任务。
老板觉得这样太低效了,于是制定了新的加工方式:小C、小U、小R之间不应该互相等待,当他们因工序等待而被阻塞时,可以直接开始新零件的加工。但是每个工序在进行中不能被打断,必须连贯地完成。
例如,有5个零件,每个零件有7道工序,分别耗时如下:
零件一:10, 10, 10, 10, 10, 10, 20
零件二:10, 10, 10, 10, 10, 10, 20
零件三:10, 10, 10, 10, 10, 10, 20
零件四:10, 10, 10, 10, 10, 10, 20
零件五:10, 10, 10, 10, 10, 10, 20
(每一行的7个数字分别表示"加工1","质检1","加工2","质检2","加工3","质检3","收尾"的耗时)
假设零件按照5、4、3、2、1的优先级开始制作,优化后的工序流程中,小C、小U、小R会更加忙碌,避免空闲。
现在给你n个零件及每个零件的工序耗时,问在经过流程优化后,所有零件加工需要花费的总时间是多少?
代码
import heapq
def solution(n: int, parts: list) -> int:
assert n == len(parts)
flag = [[0 for _ in range(len(part))] for part in parts]
b = [part[0] for part in parts]
sum_jobs = sum(b)
a = [part[1:] for part in parts]
for i in range(n):
flag[i][0] = 1
time = 0
m1, m2, m3 = 0, 0, 0
last1i, last1j = -1, -1
last2i, last2j = -1, -1
last3i = -1
q = []
heapq.heappush(q, 0)
while sum_jobs > 0:
time = heapq.heappop(q)
while q and q[0] == time:
heapq.heappop(q)
if time == m3 and last3i != -1:
sum_jobs -= 1
if time == m2 and last2i != -1 and last2j != -1:
flag[last2i][last2j + 1] = 1
sum_jobs -= 1
if time >= m1:
if time == m1 and last1i != -1 and last1j != -1:
flag[last1i][last1j + 1] = 1
sum_jobs -= 1
# Get suitable m1
found = False
for i in range(n):
for j in range(0, b[i], 2):
if flag[i][j] == 1 and j != b[i] - 1:
temi, temj = i, j
flag[temi][temj] = 0
m1 = time + a[temi][temj]
last1i, last1j = temi, temj
heapq.heappush(q, m1)
found = True
break
if found:
break
if time >= m2:
# Get suitable m2
found = False
for i in range(n):
for j in range(1, b[i], 2):
if flag[i][j] == 1:
temi, temj = i, j
flag[temi][temj] = 0
m2 = time + a[temi][temj]
last2i, last2j = temi, temj
heapq.heappush(q, m2)
found = True
break
if found:
break
if time >= m3:
# Get suitable m3
for i in range(n):
if flag[i][b[i] - 1] == 1:
temi = i
flag[temi][b[temi] - 1] = 0
m3 = time + a[temi][b[temi] - 1]
last3i = temi
heapq.heappush(q, m3)
break
return time
if __name__ == "__main__":
# You can add more test cases here
parts1 = [[7, 10, 10, 10, 10, 10, 10, 20],
[7, 10, 10, 10, 10, 10, 10, 20],
[7, 10, 10, 10, 10, 10, 10, 20],
[7, 10, 10, 10, 10, 10, 10, 20],
[7, 10, 10, 10, 10, 10, 10, 20]]
parts2 = [[5, 10, 5, 10, 5, 10],
[5, 2, 4, 6, 2, 10],
[3, 10, 2, 5]]
print(solution(5, parts1) == 200)
print(solution(3, parts2) == 57)