【问题标题】:How to find increasing subsequence of numbers with maximum sum?如何找到具有最大和的数字的递增子序列?
【发布时间】:2011-06-24 06:05:21
【问题描述】:

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

谢谢!

【问题讨论】:

标签: algorithm dynamic-programming


【解决方案1】:

我假设:

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

这让世界变得与众不同!


解决方案

让数组 A 的递增子序列 (IS) 的最优集合 S 是一组 IS,使得 A 中的每个 IS s 我们正好有一个:

  • s in S
  • S 中有一个 IS s',这样
    • sum(s') >= sum(s)
    • largest_element(s') 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]

【讨论】:

  • 你能在一个例子上运行这个吗?我不明白你在说什么。
  • '删除 S 中 s_less 和 s_more 之间的所有子序列 ' 这可以在 O(log n) 中完成。据我了解,您需要遍历每个此类元素才能将其删除。
【解决方案2】:

扫描阵列。维护一个展开树,将每个元素 x 映射到以 x 结尾的子序列的最大和。这棵展开树是按 x 排序的(不是 x 的索引),每个节点都装饰有子树最大值。最初,树只包含一个标记 Infinity => 0。要处理新值 y,请在树中搜索最左边的值 z,使得 y

【讨论】:

    【解决方案3】:

    1.) 对子序列进行排序

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

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

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

    这是亚马逊网站问我的一个采访问题,当时我在第一轮采访中因食物中毒而呕吐。我完成了第二轮面试,他们似乎不想超过那一点。如果这是一个面试问题,希望你比我做得更好,所以我的回答可能不是最好的,但希望这比说你有重复要好...

    希望这会有所帮助,

    -布莱恩·J·斯蒂纳尔-

    【讨论】:

    • 我不明白。这要求最大和增加子序列。排序如何确保您获得有效的子序列?
    【解决方案4】:

    我在 codeforces 上遇到了类似的问题。该问题可以使用带坐标压缩的分段树或使用平衡二叉搜索树来解决。详细说明请参考以下链接。

    maximum sum increasing sequence

    看完后,可以试试thiscodeforces上的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      • 2011-06-23
      相关资源
      最近更新 更多