以最佳方式减少序列

时间:2013-03-05 01:22:02

标签: algorithm

我们获得了an个数字的序列。序列a减少定义为将元素a[i]a[i+1]替换为max(a[i],a[i+1])

每个减少操作的成本定义为max(a[i],a[i+1])。减少n-1后,将获得一长度1的序列。

现在我们的目标是打印给定序列a的最佳减少成本,使得长度为1的结果序列具有最低成本。

e.g:

1

2

3

Output :

5

O(N ^ 2)解决方案是微不足道的。有什么想法吗?

EDIT1: 人们在询问我的想法,所以我的想法是成对地遍历序列,并且每对检查成本,最后以最低的成本减少对。

1 2 3
 2 3     <=== Cost is 2

将上述序列减少到

2 3

现在再次遍历序​​列,我们得到成本为3

2 3
 3       <=== Cost is 3

因此总成本为2 + 3 = 5

以上算法为O(N ^ 2)。这就是为什么我要求更优化的想法。

4 个答案:

答案 0 :(得分:2)

O(n)解决方案:

<强>高级别

基本思想是重复合并任何小于其邻居ens的元素nl及其最小邻居ns。这会产生最小的成本,因为合并的成本和结果都是max(a[i],a[i+1]),这意味着没有合并可以使元素比当前小,因此e最便宜的合并是{{1并且,该合并不能增加任何其他可能的合并的成本。

这可以通过一次通过算法来完成,方法是按顺序保持数组中的元素堆栈。我们将当前元素与其邻居(一个是堆栈的顶部)进行比较,并执行适当的合并,直到我们完成。

<强>的伪代码:

ns

Java代码:

stack = empty
for pos = 0 to length
  // stack.top > arr[pos] is implicitly true because of the previous iteration of the loop
  if stack.top > arr[pos] > arr[pos+1]
    stack.push(arr[pos])
  else if stack.top > arr[pos+1] > arr[pos]
    merge(arr[pos], arr[pos+1])
  else while arr[pos+1] > stack.top > arr[pos]
    merge(arr[pos], stack.pop)

答案 1 :(得分:0)

如果你的意思是减少“计算成本”的“成本”,即操作花费时间max(a[i],a[i+1])或者只是你想要计算的东西,我很困惑。如果是后者,则以下算法优于O(n ^ 2):

  1. 对列表进行排序,或者更准确地说,定义b[i] s.t. a[b[i]]是排序列表:如果可以使用RADIX排序,则为O(n),否则为O(n log n)。
  2. 从排序列表中的第二低项i开始:如果左/右低于i,则执行减少:每个项目为O(1),更新列表为2,O(n)总的来说。
  3. 我不知道这是否是最佳解决方案,但是对于整数而言是O(n),对于整数而言是O(n log n),否则就是。

    编辑:意识到删除预先计算步骤使其更加简单

答案 2 :(得分:0)

贪婪的方法确实有效。

您可以随时使用较小的邻居减少最小数量。

证明:我们必须在某个时候减少最小数量。邻居的任何减少都会使邻居的值至少相同(可能)更大,因此减少最小元素a [i]的操作将始终具有成本c> = min(a [i-1],a [i + 1])

现在我们需要

  1. 快速查找/删除最小数字
  2. 找到它的neigbors
  3. 我会选择2个RMQ。将操作2作为二分查找。这给了我们O(N * log ^ 2(N))

    编辑:第一个RMQ - 值。当你删除一个元素时,会有一些很大的价值 第二个RMQ - “存在”。 0或1(值存在/不存在)。要查找[i]的[例如]左邻居,您需要找到l最大的sum[l,i-1] = 1

答案 3 :(得分:0)

如果您不认为对列表进行排序是作弊的,那么请在n log n时间内进行,然后递归合并前两个条目。在这种情况下,总成本将是条目总和减去最小条目。这是最佳的,因为

  1. 费用将是n-1条目的总和(允许重复)
  2. i最小条目在费用函数中最多可出现i-1
  3. 即使列表未排序,同样的基本思想仍然有效。最佳解决方案是将最小元素与其最小邻居合并。要确保这是最佳的,请注意

    1. 费用将是n-1条目的总和(允许重复)
    2. 条目a_i最多可在费用函数中显示j-1次,其中j是包含a_i的最长连续子序列的长度,a_i }是子序列的最大元素
    3. 在最坏的情况下,序列正在减少,时间为O(n^2)