将数组的每个元素减少为零

时间:2014-05-08 03:42:53

标签: algorithm

我的数组只包含非负整数。现在我想将每个元素减少到零。允许的唯一操作是'递减范围i,j中的每个元素1'每个这样的操作的成本是1.现在问题是如何找到可以将该数组转换为所有零元素数组的此类操作的最小数量。 / p>

example: [1 2 3 0]
--->[0 1 2 0] (decrement all element in the range 0 to 2)
--->[0 0 1 0] (----------------------------range 1 to 2)
--->[0 0 0 0] (----------------------------range 2 to 2)

2 个答案:

答案 0 :(得分:2)

这感觉就像重复一样,但我找不到任何证据,所以我会回答。

在每个最优解中,不存在操作对[a,b)和[b,c),因为我们可以将它们组合为[a,c)。此外,存在层流的最佳解决方案,即,对于每对操作,它们的范围是嵌套的或不相交的,但不是部分重叠的。这是因为我们可以将[a,c)和[b,d)上的操作转换为[a,d)和[b,c)。

根据后一种限制,只有一种最佳策略可以通过重复减少最大非零间隔来导致操作。 (通过归纳证明:考虑其中interval参数最左边的减少操作和其他区间参数中的最大值。通过最左边的假设,这个区间必须包括最左边的非零。如果它排除了右边的连续非零元素,那么该元素怎么可能减少?不是从左边开始的间隔(不是层流)而不是以该元素开始的间隔(这不是最佳的),所以根本不是。)

我们所要做的就是通过算法来构建这个最优解。在Python中:

cost = 0
stackheight = 0
for x in lst:
    cost += max(x - stackheight, 0)
    stackheight = x

答案 1 :(得分:0)

我尝试了一些小例子,到目前为止,我还没有找到任何简单贪婪算法无法产生最佳解决方案的地方。我使用的方法是:

loop
    find largest element
    if largest element is zero
        break
    expand interval with non-zero values left and right around largest, until zero/boundary is encountered
    decrement values in this interval

我发现有其他解决方案具有相同步骤但没有更好的情况。例如,使用此算法:

2 3 1 2 3
1 2 0 1 2
0 1 0 1 2
0 1 0 0 1 
0 0 0 0 1
0 0 0 0 0

这就是5个步骤。这与它有着不同的顺序:

2 3 1 2 3
1 2 1 2 3
1 2 1 1 2
1 1 1 1 2
1 1 1 1 1
0 0 0 0 0

我很想看到这个策略没有产生最佳解决方案的反例。