供参考:我正在解决嵌套玩偶问题:http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=2353
我已经编写了部分以找到增长最长的子序列(nlgn版本)。例如,如果序列如下:1 2 3 1 2 1
我找到了最大的子序列:“1 2 3”并将其从中删除 原始序列。序列变为1 2 1。
我找到了最大的子序列:“1 2”然后我再删除它。序列变为1。
我找到了最大的子序列:“1”并将其删除。序列变空。
所以答案是总共3个增加3个子序列
我的问题是我得到了TLE(时间限制),我需要一种更好的方法来计算子序列。有关于使用“Dilworth定理”的暗示,但我不确定如何应用它。
答案 0 :(得分:2)
如果我正确地理解了这个问题,那么你正试图找到可以打包每个玩偶的最小数量的嵌套玩偶,而你的算法就是贪婪地制作每个阶段最大的玩偶(在它包含最多的意义上最大的玩偶)碎片,然后重复,直到所有的娃娃都被包装好。
换句话说,您正在从部分有序的集合中构建链。
任何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。