题目:一个公司下面有N个部门,现在要给每个部门分配任务,分配任务只能按照分配的顺序进行,不能同时分配两个任务,只能一个接一个的分配,但是分配完任务后,该部门可以立刻执行(不间断)。分配一个任务的时间是a,执行的时间是b。你需要做的就是决定分配给每一个部门任务的顺序,使得所有部门完成任务的总时间最短。
输入样例:
3 (代表3个部门)
2 2
3 4
1 5 (第一组数据,前面为分配时间,后面为执行时间)
2 4
4 2
3 3 (第二组数据)
Case 1:8
Case 2: 11
分析:由于这道题数据量不会很大可以采用暴力破解法(这是一个万能法),首先我们需要得到部门执行顺序的全排列组合,然后过滤出排列组合长度等于部门数的组合,在计算出每一种排列所需的执行总时间,最后计算出执行时间最短的那种组合。
代码:
# 新建同值列表
def create_list(list):
ll = []
for i in list:
ll.append(i)
return ll
# 往列表中插入一个数据的所有可能插入方法,这里要注意的是python和其他语言的不同之处,列表的直接赋
# 值操作地址空间不变,所以写了一个新建同值列表函数(很low,网上有很多种列表赋值新建地址的方式,这
# 里我就不改了)
def insert_k(list,k):
if k not in list:
result = [list]
for i in range(len(list)+1):
ll = create_list(list)
ll.insert(i, k)
result.append(ll)
else:
result = [list]
return result
# 一个过滤掉全排列后长度不等于部门数的排列的装饰器
def filter_len(fun):
def wapper(li):
result = fun(li)
re = []
for l in result:
if len(l) == len(li):
re.append(l)
return re
return wapper
# 带过滤排列装饰器的全排列函数
@filter_len
def permutations(li):
result = []
for i in li:
result.append([i])
for i in li:
ll = create_list(result)
for l in ll:
re = insert_k(l, i)
# print(re)
for r in re:
if r not in result:
result.append(r)
return result
# 计算每一种排列所需的最终时长
def all_time(task_order):
l = 0
r = 0
for index,task in enumerate(task_order):
if index+1 <= len(task_order)-1:
l += task.ready_time
next_task_time = task_order[index+1].ready_time + task_order[index+1].do_time
if next_task_time+l > l+task.do_time:
r = next_task_time+l
else:
r = l+task.do_time
return r
# 任务的类,ready_time 任务的准备时长,do_time任务的执行时长,no_dept部门id
class task_time(object):
def __init__(self,ready_time,do_time,no_dept):
self.ready_time = ready_time
self.do_time = do_time
self.no_dept = no_dept
# 主函数,计算最小时长的那种排列,并输出最小时长和部门执行顺序
if __name__=='__main__':
dept_num = input('部门数:')
task_list = []
max_time = 0
for i in range(dept_num):
ready_time = input('第%sth部门的分配时长:'%i)
do_time = input('第%sth部门的执行时长:'%i)
task_list.append(task_time(ready_time,do_time,i))
max_time += ready_time + do_time
task_permutations = permutations(task_list)
min_time = (max_time,)
for task_order in task_permutations:
l = all_time(task_order)
# print(l)
if l < min_time[0]:
min_time = (l,task_order)
else:
continue
print(min_time[0],'部门顺序:',min_time[1][0].no_dept,min_time[1][1].no_dept,min_time[1][2].no_dept)