我假设:
这让世界变得与众不同!
解决方案
让数组 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]