使用“最长增长子序列算法(nlgn)”增加子序列的数量

时间:2014-02-11 20:17:44

标签: algorithm

供参考:我正在解决嵌套玩偶问题:http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=2353

我已经编写了部分以找到增长最长的子序列(nlgn版本)。例如,如果序列如下:1 2 3 1 2 1

  1. 我找到了最大的子序列:“1 2 3”并将其从中删除 原始序列。序列变为1 2 1。

  2. 我找到了最大的子序列:“1 2”然后我再删除它。序列变为1。

  3. 我找到了最大的子序列:“1”并将其删除。序列变空。

  4. 所以答案是总共3个增加3个子序列

    我的问题是我得到了TLE(时间限制),我需要一种更好的方法来计算子序列。有关于使用“Dilworth定理”的暗示,但我不确定如何应用它。

1 个答案:

答案 0 :(得分:2)

算法

如果我正确地理解了这个问题,那么你正试图找到可以打包每个玩偶的最小数量的嵌套玩偶,而你的算法就是贪婪地制作每个阶段最大的玩偶(在它包含最多的意义上最大的玩偶)碎片,然后重复,直到所有的娃娃都被包装好。

换句话说,您正在从部分有序的集合中构建链。

Dilworth's theorem说:

  

任何antichain中的最大元素数等于最小值   集合的任何分区中链的数量

因此您可以通过计算单个反链中的元素来计算链的数量。

你可以用你现在正在做的非常类似的方式构建反链,通过按宽度递减顺序排列玩偶,然后在高度内找到最长的增加子序列。

请注意,使用此方法可以通过测量反链的长度得到答案,并且您只需要运行一次最长的增加子序列算法,因此它应该快得多。

实施例

在您的(1,1),(1,1),(2,2),(3,3),(1,1),(2,2),(1,1)的例子中,我们首先按宽度排序依次排序:

(3, 3), 
(2, 2), 
(2, 2), 
(1, 1), 
(1, 1), 
(1, 1), 
(1, 1)

然后提取高度:

3,2,2,1,1,1,1

然后找到增长最长的子序列(请注意,每个元素必须与之前相同或更高,因此严格来说,您会找到最长的非递减子序列):

1,1,1,1

长度为4,答案是4。