在O(n 3 )时间内,问题很容易解决。问题是这样的:
数字行上有N个唯一的点。你想要涵盖每一个 带有一些间隔的数字线上的单点。您可以 在任何地方放置一个间隔,创建一个间隔需要
B + MX
interval,其中B
是创建间隔的初始成本,和X
半长区间的长度,M
是每个成本 间隔的长度。您想要找到涵盖每个的最低成本 单一间隔。
示例数据:
Points = {0, 7, 100}
B = 20
M = 5
因此,最佳解决方案将是57.50,因为您可以在成本20 + 3.5×5处构建间隔[0,7]并在成本100 + 0×5处建立[100,100]的间隔,这相当于57.50。
我有一个O(n 3 )解决方案,其中DP是覆盖[left, right]
点的最低成本。所以答案将在DP[1][N]
。对于每对(i,j)
,我只是迭代k = {i...j-1}
并计算DP[i][k] + DP[k + 1][j]
。
然而,这个解决方案是O(n 3 )(我认为有点像矩阵乘法)所以它在N>上太慢了。 2000.有什么办法优化这个?
答案 0 :(得分:2)
这是一个二次解决方案:
按坐标对所有点进行排序。拨打积分p
。
我们会保留一个数组A
,以便A[k]
是覆盖第一个k
点的最低费用。将A[0]
设置为零,将所有其他元素设置为无穷大。
对于从k
到0
的每个n-1
以及从l
到k+1
的每个n
,设置{{1} }}
您应该能够说服自己,最后A[l] = min(A[l], A[k] + B + M*(p[l-1] - p[k])/2);
是涵盖所有A[n]
点的最低费用。 (我们考虑了所有可能的最小覆盖间隔,我们从"从左到右"在某种意义上这样做。)
你可以加快速度,使其在O(n log n)时间内运行;用以下内容替换第3步:
设置n
。对于A[1] = B
到k
的每个2
,请设置n
。
这里的想法是我们要么延长前一个间隔以覆盖下一个点,要么我们在A[k] = A[k-1] + min(M/2 * (p[k-1] - p[k-2]), B)
结束前一个间隔并在p[k-2]
开始一个新的间隔。我们做出决定时唯一需要知道的就是两点之间的距离。
另请注意,在计算p[k-1]
时,我只需要A[k]
的值。特别是,您不需要存储整个数组A[k-1]
;只是它最近的元素。