因此,我们有一个T天的时间表,其中必须执行一些任务。 每项任务都有罚分。如果任务未在给定时间线内执行,则其得分将在最终罚分中累加。在给定开始时间之后,每个任务都可以仅执行。
输入将以以下格式给出:
Ť
得分Quantity_of_task Starting_time
例如:
T = 10
140 5 4
这意味着必须从第4天开始执行5个惩罚分数为140的任务。 您可以在特定日期执行最多1个任务。
目标是尽量减少最终的罚分。
我试图做的事情:
Example -
T = 10
Input size = 5
150 4 1
120 4 3
200 2 7
100 10 5
50 5 1
我根据惩罚分数对列表进行了排序,并且贪婪地将具有高罚分的任务分配到相应的日期,即
分数最高为200的2个任务分配到第7天和第8天
具有次高得分150的4个任务被分配到1,2,3,4天
具有次高得分120的4个任务被分配到5,6,9,10天
将时间表作为 150 150 150 150 120 120 200 200 120 120
遗漏任务:
10个任务,100分= 1000罚款
5个任务,50分= 250罚款
最终罚款= 1250。
这需要O(T * input_size)。有更优雅和优化的方式吗?
输入大小和T都有10 ^ 5的约束。
感谢。
答案 0 :(得分:0)
如果将可用天数存储在有序集中,则可以更快地执行算法。
例如,C ++提供了一个带有lower_bound方法的有序集,该方法将在开始时间后的第一个可用日期的O(logn)时间内找到。
总的来说,这应该给出一个O(nlogn)算法,其中n = T + input_size。
例如,我怀疑当你从第3天开始分配你的4个惩罚任务120时,你当前的代码将循环3,4,5等等。直到你找到一个尚未分配的日子。现在,您可以使用对lower_bound的单个O(logn)调用替换此O(n)循环,以查找第一个未分配的日期。当你贪婪地指定日期时,你也应该从集合中删除它们,这样它们就不会被分配两次。
请注意,只有T天,因此最多只有T天分配。例如,假设所有任务都有开始时间1和数量T.然后第一个任务将花费O(Tlogn)时间来分配,但所有后续任务只需要一次调用lower_bound(因为没有剩余的时间来分配),所以每个都需要O(logn)。