在给定时间内可以完成的最大任务数

问题描述

我最近在论坛上遇到了这个问题: 你会得到一条从 0 到 10^9 的直线。您从零开始,您可以执行 n 个任务。第 i 个任务位于行中的第 i 点,需要“t”时间来执行。要执行任务,您需要到达点 i 并在该位置花费 't' 时间。

示例:(5,8) 位于 5,因此行驶距离为 5,工作量为 8。 总工作量的计算方式为旅行距离 + 完成工作所需的时间。 走一单位路径需要一秒。

现在给我们总共T秒,我们需要完成尽可能多的任务并回到起始位置 求你能在时间 T 内完成的最大任务数。

示例:

3 16 - 3 个任务和 16 个单位的总时间

2 8 - 任务 1 排在第 2 位,需要 8 秒才能完成

4 5 - 任务 2 排在第 4 位,需要 5 秒才能完成

5 1 - 任务 3 排在第 5 位,需要 1 秒才能完成

输出:2

说明: 如果我们在位置 2 执行任务 1 需要 8 秒,那么到达位置 2 需要 2 秒,完成任务需要 8 秒,而我们只有 6 秒,不足以完成其他任务

另一方面,跳过第一个任务让我们有足够的时间完成其他两个任务。

前往地点并返回需要 2x5 = 10 秒,而在地点 4 和 5 执行任务需要 5+1 = 6 秒。花费的总时间为 10s+6s=16s。

我是图形和 DP 的新手,所以我不确定使用哈密顿循环、背包或最长路径的方法。 有人可以帮助我用最有效的方法解决这个问题。

解决方法

让我们根据距离从第一个任务迭代到最后一个任务。随着我们的进行,很明显,在减去 2 * distance(i) + effort(i) 以将当前任务视为我们的最后一个之后,我们可以通过贪婪地将尽可能多的早期任务积累到剩余时间中来找到我们可以完成的最多任务,并通过增加对它们进行排序努力。

因此,一个有效的解决方案可以将看到的元素插入到按努力排序的数据结构中,动态更新迄今为止的最佳解决方案。 (我最初想到使用 treap 和二分搜索,但 j_random_hacker 在此答案下方的评论中建议了一种更简单的方法。)

,

建议:

为每个任务 n 创建一个这样的图表

enter image description here

将所有任务的这些图表连接起来。

enter image description here

运行旅行商算法以找到完成所有任务的最短时间(=访问组合图中的所有节点)

按顺序删除任务。这将为您提供执行不同数量任务的结果集合。选择在时间限制内完成最多任务的一项。

既然您要最大化执行的任务数量,请先删除最长的任务,这样您就会剩下许多短的任务。