我正在网上进行编程练习,我发现了这个问题:
两台打印机以不同的速度工作。第一台打印机在
x
分钟内生成一张纸,而第二台打印机在y
分钟内生成一张纸。要总共打印N
份论文,如何将任务分配给这些打印机,以便打印时间最短?
练习为我提供了三个输入x
,y
,N
,并要求输出最短时间。
输入数据:
1 1 5
3 5 4
答案:
3 9
我尝试将第一台打印机的任务设置为a
,将第二台打印机的任务设置为N-a
。最有效的打印方式是让它们具有相同的时间,因此最小时间为((n * b)/(a + b))+ 1。但是这个公式是错误的。
然后我尝试用蛮力的方式来解决这个问题。我首先在a
和b
中区分哪一个更小(更快)。然后我继续向更快的打印机添加一张纸。当打印机所需的时间比打印另一台打印机的一张纸的时间长时,我将一张纸送到较慢的打印机,然后减去更快打印机的时间。
代码如下:
def fastest_time (a, b, n):
""" Return the smalles time when keep two machine working at the same time.
The parameter a and b each should be a float/integer referring to the two
productivities of two machines. n should be an int, refering to the total
number of tasks. Return an int standing for the minimal time needed."""
# Assign the one-paper-time in terms of the magnitude of it, the reason
# for doing that is my algorithm is counting along the faster printer.
if a > b:
slower_time_each = a
faster_time_each = b
elif a < b :
slower_time_each = b
faster_time_each = a
# If a and b are the same, then we just run the formula as one printer
else :
return (a * n) / 2 + 1
faster_paper = 0
faster_time = 0
slower_paper = 0
# Loop until the total papers satisfy the total task
while faster_paper + slower_paper < n:
# We keep adding one task to the faster printer
faster_time += 1 * faster_time_each
faster_paper += 1
# If the time is exceeding the time needed for the slower machine,
# we then assign one task to it
if faster_time >= slower_time_each:
slower_paper += 1
faster_time -= 1 * slower_time_each
# Return the total time needed
return faster_paper * faster_time_each
当N
较小或x
且y
较大时,它可以正常工作,但需要花费大量时间(我猜超过10分钟)来计算{{1} }和x
非常小,即输入为y
。
我相信有一个更好的算法来解决这个问题,有人可以给我一些建议或提示吗?
答案 0 :(得分:1)
给出表格中的输入
x, y, n = 1, 2, 159958878
这应该有效
import math
math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
这适用于所有样本输入。
In [61]: x, y, n = 1,1,5
In [62]: math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
Out[62]: 3.0
In [63]: x, y, n = 3,5,4
In [64]: math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
Out[64]: 9.0
In [65]: x, y, n = 1,2,159958878
In [66]: math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
Out[66]: 106639252.0
修改强>
这不适用于@Antti提到的情况,即x, y, n = 4,7,2
。
原因是我们首先考虑的是较短的时间。因此,解决方案是找到两个值,即考虑更短的时间和考虑更长的时间,然后选择结果值中较小的一个。
因此,这适用于包括@ Antii的所有案例
min((math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y)),
math.ceil((min((x,y)) / float(x+y)) * n) * max((x,y))))
虽然可能会出现一些极端情况,您可能需要稍微更改一下。