[算法]时间与收益

时间与收益

问题地址

题目描述

Description
Given a set of n jobs where each job i has a deadline and profit associated to it. Each job takes 1 unit of time to complete and only one job can be scheduled at a time. We earn the profit if and only if the job is completed by its deadline. The task is to find the maximum profit and the number of jobs done.
Input
The first line of input contains an integer T denoting the number of test cases.Each test case consist of an integer N denoting the number of jobs and the next line consist of Job id, Deadline and the Profit associated to that Job.
Constraints:1<=T<=100,1<=N<=100,1<=Deadline<=100,1<=Profit<=500
Output
Output the number of jobs done and the maximum profit.

Sample Input 1

2
4
1 4 20 2 1 10 3 1 40 4 1 30
5
1 2 100 2 1 19 3 2 27 4 1 25 5 1 15

Sample Output 1

2 60
2 127
题目解析
  1. 给定N个工作,每个工作有其截至时间,和做了这个工作所获得的收益
  2. 每做一个工作,时间就减少1
  3. 给定一个时间,问你该时间内可以获得的最大价值是多少
错误思路
  • 如果每次都选择最大价值的任务话,那么就会有一些任务选不到,比如说第一次选择了截至时间为2的任务,那么第二次 就无法选择截至时间为1的任务(已经结束了)

    ​ eg 2 100 1 90 如果选择100,第二次就无法选择90

  • 如果每次都选择该时间内最大价值的任务,这样结果一定是每个时间由一个任务组成,那么就会漏解

    ​ eg: 2 20 , 2 21, 1 10 ,1 11 如果选择11 21 就会漏掉20 21

由题意可知,对于每个截至时间为N的工作我们最多选N次,

所以我们可以想到如下办法,

  1. 第一次选择截至时间为1中最大的1个数

    扫描二维码关注公众号,回复: 10537086 查看本文章
  2. 第二次选择截至时间为2中最大的两个数,把第一次的最大值也算上,更新比较留下2个最大的

  3. 第三次选择截至时间为3中最大的三个数,把第二次的最大值也算上,更新比较留下3个最大的

  4. 依次类推,这样就能获得最佳的答案

但这样未免太复杂,并且如果截至时间为x中没有x个数,就会漏解,但根据此思路,有如下办法

思路解析
  1. 创建一个一维数组,长度为最大截至时间
  2. 将(任务,价值)按照价值排序,获得一个list[(任务,价值)]
  3. 每次遍历list,取出价值最大的,以任务为下标放在数组里
    1. 如果该位置没元素就放入
    2. 有元素则去它前面的位置观察是否可以放入,
    3. 若超出数组长度则舍弃.重复
  4. 遍历结束后,数组中的值就是我们所选的值

总结一下,如果当前作业可以在不错过截止日期的情况下可以完成,请将当前作业添加到结果中。

代码实现

python

if __name__ == '__main__':
    for i in range(int(input())):
        _ = input()
        arr = list(map(int, input().strip().split(" ")))
        l = []
        max_num = -1  # 
        for i in range(0, len(arr), 3):
            max_num = max(max_num, arr[i + 1])
            l.append((arr[i + 1], arr[i + 2]))
        max_arr = sorted(l, reverse=True, key=lambda x: x[1])  # 打包,按照价值大小排序
        res_arr = [0] * max_num  # 创建一个数组,用于存放结果
        count = 0  # 计算数量
        for temp in max_arr:
            index = temp[0] - 1 # 对应数组下标
            while index >= 0 and res_arr[index] != 0:
                index -= 1
            if index != -1: # 代表放入在了数组中,本次选择有效
                res_arr[index] = temp[1]
                count += 1
        print(count, sum(res_arr))
发布了71 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33935895/article/details/103299107