将数组分区为最大组数

时间:2015-10-23 15:08:53

标签: algorithm recursive-backtracking

只有一条规则可以遵循:每组的总和应该大于或等于右侧的组。

我的猜测是构建一个树,其中存在所有分区选项,然后是递归回溯。

例如,阵列14 13 2 11

结果:3。3组({14},{13},{2,11})

你认为我的猜测是真的吗?如果没有,你有其他解决方案吗?

1 个答案:

答案 0 :(得分:1)

这是一个O(n^2) - 时间算法,其中n是数组的长度。我撤回了我的评论,即“可能”更快。

有一个更简单的O(n^4) - 时间算法,它说明了动态程序的主要思想。我们准备一个条目表T(i, j),其中i, j条目包含最大数量的组,数组元素索引[0, j)可以适当地分组,以便最后一个组具有索引[i, j)

我们有一个复发

T(0, j) = 1 for all j
T(i, j) =          max          T(h, i) + 1,
          h : S(h, i) ≥ S(i, j)

其中S(i, j)是索引为[i, j)的数组元素的总和,空的最大值为负无穷大。答案是

max T(i, n).
 i

我们转到O(n^4),因为对于O(n^2)表条目,我们计算的O(n)项的最大值均为O(n)项。

我们进行了两次优化。第一个很简单:随着我们变化S(h, i),逐步更新总和h。这会将费用降至O(n^3)。我们可以对S(i, j)执行相同的操作,但是假设我们明智地将其从最大循环中提升出来,则效果不佳。

第二个取决于非负条目。对于特定i, j,有效h的集合是[0, k)之类的间隔,可能为空。对于i固定和j减少,总和S(i, j)不增加,因此间隔不会缩小。这意味着我们也可以逐步更新最大值,产生O(n^2) - 时间算法。