如何找到解决所有 N 个问题所需的最短时间?
Posted
技术标签:
【中文标题】如何找到解决所有 N 个问题所需的最短时间?【英文标题】:How to find the minimum time required to solve all N problems? 【发布时间】:2015-05-22 17:33:13 【问题描述】:我试图解决这个问题,但即使过了几个小时我也无法解决 完全理解问题。我什至无法上来 使用任何蛮力技术。这就是问题:
有 N 个成员和 N 个问题,每个成员必须准确解决 1 个问题。团队中只允许一名成员阅读 在任何人开始解决之前的问题陈述。
请注意,并不是每个人一开始都阅读过这些问题。所以,要解决 成员需要知道某个队友的陈述的问题 已经认识他们了。知道问题一次后,会员才有资格 向其他队友解释(一次一位队友)。你可以 假设解释(1或N个问题)总是需要D 分钟。在解释过程中,两名涉事成员都不会 可以做任何其他事情。
问题具有不同的难度级别。你可以假设它 将花费 Ti 分钟来解决第 i 个问题,无论哪个 会员解决了。
给定一个团队的数据,他们最少可能需要多少时间 能解决所有问题吗?
输入
N D
2 100
T=[1 2]
Output
102
允许成员 1 在开始时间之前知道问题。他开始 比赛开始时向成员 2 解释问题。解释结束于 第 100 分钟。然后他们俩立即开始解决 并行的问题。成员 1 在第 101 分钟解决了第一个问题 成员 2 在第 102 分钟解决了第 2 个问题。
解码这类问题并解决它的最佳方法是什么?
【问题讨论】:
N
可以有多大?我们可以选择谁在开始时间之前了解所有问题,还是总是成员 1?
@IVlad N≤3×10^3 。是的,我们可以选择任何成员..不一定是 1..
问题陈述没有多大意义。鉴于您陈述的条件,解决所有问题总是需要D + N
分钟。现在,如果成员可以在向他解释问题后立即开始解决问题(即他不必等待所有问题都得到解释),那么您就有了要解决的问题。
@JimMischel 但是一个成员只能解决一个问题,一旦他解决了问题,他就必须坐 Idle 。所以我们需要确保在最短的时间内解决所有问题。
【参考方案1】:
这让我想起了Huffman coding。
我不确定以下方法是否最佳,但在实践中它可能会给出一个很好的答案。
-
选择最简单的两个问题 T0 和 T1,并将它们替换为由时间 D+max(T0,T1) 组成的单个问题。
重复直到剩下一个问题
如果将问题存储在二进制堆中,则可以在 O(logN) 中找到两个最简单的问题,因此总体而言这是 O(NlogN)。
示例
假设我们有 1,3,4,6 和 D=2。
我们首先将 1 和 3 组合成 2+max(1,3)=5。新列表是 4,5,6
然后我们将 4 和 5 结合起来,使 2+max(4,5)=7。新列表是 6,7。
然后我们将 6 和 7 组合成 2+max(6,7)=9。
这表示以下过程。
t=0 A shares with B
t=2 A starts problem 6, B shares with C
t=4 B starts problem 4, C shares with D
t=6 C starts problem 3, D starts problem 1
t=7 D finishes
t=8 A finishes, B finishes
t=9 C finishes
【讨论】:
其实我到现在也没找到反例,你有吗?如果事实证明这是最优的,那就太好了。 我没有反例,我只是没有勇气尝试证明...... 那么我们是否需要对时间进行排序并使用贪心策略求解,即先求解最高执行时间,然后再求解第二高,等等?? 不完全是,它更像是一种贪心策略,最后解决两个最短的任务(其中一个任务要么是原始问题之一,要么是已经合并的问题的组合) @PeterdeRivaz 为什么我们不能对时间 T 进行排序以获得两个最简单的问题。这需要 O(n^2lohn) 时间,因为我们必须在每次合并两个最简单的问题后进行排序。【参考方案2】:团队的每个成员(阅读问题的人除外)
必须听到问题。也就是说,问题必须被告知N - 1
次。
对于N = 2
,这可以在D
分钟内完成,
对于2 < N <= 4
在2D
分钟,
对于4 < N <= 8
在3D
分钟等。
如果N
不是 2 的精确幂,那么有些人必须说完
问题至少比其他人早D
分钟。
提早完成的人可以继续工作
最难的问题,把更容易的问题留给后来完成的问题。
如果某些问题需要时间Ti > D
和N
都不是精确的
2 的幂,也不小于 2 的精确幂,您可能想要
有人比D
分钟前停止告诉问题更多
最后的问题讲完了。
如果有些问题需要时间Ti > 2D
那么你可能需要考虑
让一些人停止讲述问题并开始研究真正的问题
即使N
是 2 的精确幂,也能尽快解决难题。
由于解决一个问题是每个成员的关键路径,
但讲述在多个成员的关键路径中,
任何人在完成之前解决问题都是没有意义的
他们将要解决的所有问题。
每D
分钟后知道问题的人数
讲问题的人数增加。
讲问题的人数增加了讲问题的人数
正在讲述问题(即,刚刚学会了
问题)减去当时开始解决问题的人数。
一个好的“蛮力”方法可能是对问题进行排序
按难度;然后找出最后一个人听到的时间
如果在此之前没有人开始处理这些问题;
找出最后一个人何时结束;
然后尝试提前D
分钟或2D
分钟开始问题,
或3D
分钟等,但永远不要启动较短的运行
在一个运行时间较长的问题之前出现问题。
【讨论】:
“团队的每个成员......必须听到问题”---不。第一个成员实际解决所有问题而不是描述可能会更快。 @Petr - 不,问题陈述说每个成员必须解决一个问题。 哦,抱歉,没注意到这个 Peter de Rivaz 的解决方案在大多数情况下看起来像是一个很好的启发式方法,我试图找到一个反例但没有成功。我的猜测是这将是最好的答案。【参考方案3】:问题陈述对解释部分有些模棱两可。根据语句的解释方式,可能有以下解决方案:
如果你假设你可以在 D 分钟内解释 N 个问题,那么解释一个问题需要 N/D
分钟。让我们称之为Te
,表示“解释时间”。而解决问题i
的时间是Ti
,我们知道它等于i
分钟。
所以在比赛开始时,成员 1(知道所有问题)向成员 2 解释问题 N。这需要 Te
分钟。然后成员 2 开始处理问题 N(需要 N 分钟解决),成员 1 开始向成员 3 解释问题 N-1。这种情况一直持续到成员 1 向成员 N 解释问题 2。此时,成员 N 开始处理问题 2,成员 1 开始处理问题 1。
假设有 4 个问题、4 个团队成员和D=8
。所以Te=2
。
Time Description
0 Member 1 begins explaining Problem 4 to Member 2
2 Member 2 begins working on Problem 4
Member 1 begins explaining Problem 3 to Member 3
4 Member 3 begins working on Problem 3
Member 1 begins explaining Problem 2 to Member 4
6 Member 2 completes problem 4
Member 4 begins working on Problem 2
Member 1 begins working on Problem 1
7 Member 3 completes Problem 3
Member 1 completes Problem 1
8 Member 4 completes Problem 2
无论D
或N
的值如何,这似乎都是最佳解决方案:安排它以使解决时间最长的问题尽早开始。
我怀疑问题陈述是用其他语言给出的问题的英文翻译,或者可能是对最初用英语编写并翻译成其他语言的内容的重新翻译。因为如果那是最初的问题陈述,那么写它的人应该被禁止再写问题。
【讨论】:
【参考方案4】:完成任何一项任务所需的时间长度似乎是C * D + T, where C is a positive integer less than N
的形式,并且必须考虑所有N-1
的提前期。假设我们犯了一个错误,而最佳解决方案实际上应该有一个任务加上更长的交货时间——所以有些C * D + Tj < C * D + Ti, where Ti < Tj
,这是不可能的。
因此,对对的总和进行一次迭代(假设输入已排序):
solution = maximum (T2 + (n-1) * D, T3 + (n-2) * D...D + Tn)
【讨论】:
以上是关于如何找到解决所有 N 个问题所需的最短时间?的主要内容,如果未能解决你的问题,请参考以下文章