查找最高塔的最小可能高度

时间:2018-10-06 07:03:00

标签: algorithm math dynamic-programming greedy

我有高度为H = h1,h2,h3 ...的塔,并且我有一台切割机,它仅切割具有特定长度A = a1,a2,a3 ..的每个塔,并且我有m次切割找到最小值最高塔的可能高度。

对于ex- H = 1,4,9,16,25和A = 1,2,3,4,5

m = 3(仅3切)

最小可能的高度是15,因为切割后的数组看起来像H = 1,4,9,12,15(分别在塔上应用0、0、0、1、2切割后)

我尝试的方法:我认识到它是贪婪的问题(如果我错了,请纠正我),然后我尝试对H数组进行排序,并尝试使用一种简单的方法先将最大高度减小到不再保持最大高度,然后再减小找到了新的最大值,然后再次应用相同的步骤,这是正确的,但是它太幼稚,要花费大量时间来获取较大的值?

采取时间步骤:每次O(N)都查找最大元素,也不是每次都进行排序。

n的约束最大为10 ^ 5,m的约束大约为10 ^ 18。

有没有更好的方法?指导我!

1 个答案:

答案 0 :(得分:4)

形式为minimum .. of the maximum ..的问题通常可以通过二进制搜索的想法来解决。通过对度量应用二进制搜索以优化minimum possible height of the highest tower,我们可以为给定问题制定O(N * log(M))解决方案。共享相同的伪代码:

start = 0, end = 10^18
while start < end:
    cuts_used = 0 // Number of cuts used till now
    mid = (start + end) / 2
    // Let's see if its possible to trim down all the towers such
    // that height of each tower <= mid
    for i in range(0,N):
        if H[i] > mid:
            // Calculate the number of cuts required to bring H[i]<= mid
            cuts_required = ceil(1.0 * (H[i] - mid) / A[i])
            cuts_used += cuts_required
    // After iterating over the towers
    if cuts_used > M:
        // We're exceeding the number of cuts, hence increase the tower height
        start = mid + 1
    else:
        // We still have some more cuts left, so let's cut more
        end = mid - 1

return start

start应该是我们的最佳答案,因为我们的条件定义为while start < end。考虑一下我们的范围是start = 1和end = 2的情况。给定情况的中点是[(1 + 2)/ 2] =1。

  • 现在,如果1确实是我们的最佳答案,那么当mid = 1时cuts_used将为<= M,因此我们的对数将移至中点-1,即0。因此,范围将开始= 1,结束= 0,我们将停止循环。显然start将是我们的解决方案。

  • 现在,对于另一种情况,当2是解决方案时,中= 1的cuts_used将> M,因此我们的算法将开始移动到中+ 1,范围将变为开始= 2, end = 2-导致我们停止循环。

在任何一种情况下,显然start是我们的最佳解决方案。

另外,请注意,计算ceil((H[i] - mid) / A[i])时,我们不能进行整数除法,因为我们会丢失浮点数,因此ceil将无法按预期工作。因此,应该考虑使用ceil(1.0 * (H[i] - mid) / A[i])来将结果强制转换为浮动值,以用于ceil的输入。