如何找到具有最大总和的数字的增加子序列?

时间:2011-02-09 15:59:29

标签: algorithm dynamic-programming

如何找到具有最大总和的数字的增加子序列。 我找到O(N ^ 2),但我想知道O(N log N)。

谢谢!

4 个答案:

答案 0 :(得分:3)

我假设:

  • 你根本不关心子序列长度。
  • 子序列不需要是连续的

这会使世界与众不同!


<强>解决方案

让数组S的增加子序列(IS)的最佳集合A成为一组IS,这样s中的每个IS A我们只有一个的:

  • s in S
  • s'中有一个IS S
    • sum(s')&gt; = sum(s)
    • largest_element(s')&lt; = largest_element(s)

最佳集合S可以通过子序列的最大元素及其总和来排序 - 顺序应该相同。这就是我后来最小/最大序列的意思。

然后我们的算法必须找到A的最佳集合并返回其最大序列。 S可以通过以下方式计算:

S := {[]} //Contains the empty subsequence
for each element x in A:
   s_less := (largest sequence in S that ends in less than x)
   s := Append x to s_less
   s_more := (smallest sequence in S that has sum greater than s)

   Remove all subsequences in S that are between s_less and s_more 
    (they are made obsolete by 's')

   Add s to S

S中最大的子序列是数组中最大的子序列。

每个步骤都可以在O(log n)中实现,S是一个平衡的二叉树。 n个步骤给出了O(n * log n)的总复杂度。

警告:在我的伪代码中很可能会出现一些+ - 1错误 - 发现它们是留给读者的一种锻炼:)


我会尝试提供具体示例。也许它有助于使想法更清晰。 到目前为止,最右边的子序列总是最好的,但其他的子序列是因为将来它们可能会成长为最重的序列。

curr array | Optimal Subsequences
[]              []

//best this we can do with 8 is a simgleton sequence:
[8]             [] [8]

//The heaviest sequence we can make ending with 12 is [8,12] for a total of 20
//We still keep the [8] because a couble of 9s and 10s might make it better tahn 8+12
[8,12]          [] [8] [8,12]

[8,12,11]       [] [8] [8,11] [8,12]
[8,12,11,9]     [] [8] [8,9] [8,11] [8,12]

//[8,9,10] makes [8,11] and [8,12] obsolete (remove those).
//It not only is heavier but the last number is smaller.
[8,12,11,9,10]  [] [8] [8,9] [8,9,10]

答案 1 :(得分:1)

扫描阵列。保持一个splay树,将每个元素x映射到以x结尾的子序列的最大总和。此展开树按x(不是x的索引)排序,每个节点都使用子树最大值进行修饰。最初,树只包含一个哨兵Infinity =&gt; 0.要处理新值y,在树中搜索最左边的值z,使得y <= z。 Splay z到根。 z的左子节点的子树最大M是y可以扩展的子序列的最大总和。将(y,M + y)插入树中。最后,返回树最大值

答案 2 :(得分:0)

1。)对子序列进行排序

2。)遍历你的列表,将下一个元素添加到前一个元素

3。)一旦你到达两个总和大于maximum_sum的元素,停止。之前的所有内容可以组合在一起,成为&lt; = maximum_sum。

这假设您要求添加两个元素以生成maximum_sum。一般概念可以推广为0-N求和,其中N是“数字”的长度。但是,您没有说明您实际添加的内容,因此我做了一个假设。此外,我不确定这是否会给你数字的“最长”子序列,但是它会给你一个N log N中数字的子序列。

这是亚马逊在第一轮采访中从食物中毒中掏出我的胆量时问及我的采访问题。我完成了两次采访,他们似乎并不希望超越这一点。如果这是一个面试问题,希望你做得比我做的更好,所以我的答案可能不是最好的,但希望它比说你有重复更好......

希望这会有所帮助,

-Brian J. Stinar -

答案 3 :(得分:0)

我在codeforces上遇到了类似的问题。可以使用具有坐标压缩的分段树或使用平衡二叉搜索树来完成该问题。有关详细说明,请参阅以下链接。

maximum sum increasing sequence

阅读后,您可以尝试this代码强制问题。