带权区间调度【Python】

算法作业

有n项工作,工作j的开始时间是sj,结束时间是fj,完成工作j获得的报酬是wj;
如果两项工作的时间没有重叠,则同一个人可以完成两项工作;目标:在同一个人可以完成的工作中,找出所获报酬最大的工作集合;
输入:
第一行输入工作的数量
第二行开始,每行输入一个工作编号和对应的报酬、开始时间以及结束时间,以空格隔开,时间按XX:YY:ZZ的格式
输出:
第一行输出所获报酬最大的工作编号集合
第二行输出对应的最大报酬
例子:
输入:
3
3 6 09:10:00 10:10:00
1 10 08:00:00 09:00:00
2 8 08:30:00 9:30:00
输出:
{1,3}
16

1 5 08:00:00 9:57:02
2 6 09:00:00 11:00:00
3 7 10:00:00 11:50:00
4 8 11:30:00 13:10:00
5 9 12:00:00 14:00:00
from collections import defaultdict


# 按结束时间排序
def Sort(W):
    n = len(W)
    for i in range(n):
        for j in range(n - i - 1):
            if W[j][3] > W[j + 1][3]:
                W[j], W[j + 1] = W[j + 1], W[j]
    return


# 找出前一个和它不冲突的
def PRE(W):
    n = len(W)
    PRE = defaultdict(list)
    for i in range(n - 1, -1, -1):
        PRE[W[i][0]] = '0'
        for j in range(i - 1, -1, -1):
            if W[j][3] <= W[i][2]:
                PRE[W[i][0]] = W[j][0]
                break
    return PRE


# 带权区间调度
def ALG(W, PRE):
    # 每个点走过的路径
    L = defaultdict(list)
    L[W[0][0]].append(W[0][0])
    # 报酬最大路径
    most = []
    # 每个点的最大报酬
    T = defaultdict(int)

    n = len(W)
    for i in range(n):
        if i > 1:
            L[W[i][0]] = L[PRE[W[i][0]]].copy()
            L[W[i][0]].append(W[i][0])
        T[W[i][0]] = W[i][1]
        # 如果当前报酬(本身报酬+不冲突的前一个点的报酬) > 前一个点的报酬,则更新本点报酬
        if T[W[i][0]] + T[PRE[W[i][0]]] > T[W[i - 1][0]]:
            T[W[i][0]] += T[PRE[W[i][0]]]
            most = L[W[i][0]]
        else:
            T[W[i][0]] = T[W[i - 1][0]]

    print("工作编号:", most)
    print("最大报酬:", T[W[n - 1][0]])
    return


if __name__ == '__main__':
    # 输入
    n = int(input("请输入工作数量:"))
    W = []
    print("请依次输入:工作编号、报酬、起始时间、结束时间:")

    for i in range(n):
        job, wage, start_time, end_time = input().split(" ")
        s_h, s_m, s_s = map(int, start_time.split(":"))
        e_h, e_m, e_s = map(int, end_time.split(":"))
        start = s_h * 3600 + s_m * 60 + s_s
        end = e_h * 3600 + e_m * 60 + e_s
        W.append((job, int(wage), start, end))

    # 按结束时间排序
    Sort(W)
    print("按结束时间排序后:", W)
    print("每个工作上一个不冲突",  (PRE(W)))
    ALG(W, PRE(W))
 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值