间隔/点优化DP

时间:2012-12-15 05:44:09

标签: algorithm

在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.有什么办法优化这个?

1 个答案:

答案 0 :(得分:2)

这是一个二次解决方案:

  1. 按坐标对所有点进行排序。拨打积分p

  2. 我们会保留一个数组A,以便A[k]是覆盖第一个k点的最低费用。将A[0]设置为零,将所有其他元素设置为无穷大。

  3. 对于从k0的每个n-1以及从lk+1的每个n,设置{{1} }}

  4. 您应该能够说服自己,最后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] = Bk的每个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];只是它最近的元素。