一道算法题随笔(2)

题目:一个公司下面有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)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值