由于每个(X,Y)对的两个值必须按顺序排列(X < Y),并且一个对的Y值必须小于下一个对的X值,因此您实际上正在沿着一个维度构建一个连续的值链。 您只需按Y值排序即可。
给定这个示例数据:
(15,40) (5,8) (1,10) (6,8) (9,20) (2,4) (36,37) (34,35) (9,14) (30,31)
按Y排序以获得:
(2,4) (6,8) (5,8) (1,10) (9,14) (9,20) (30,31) (34,35) (36,37) (15,40)
然后循环遍历,如果其X大于链中最后一个Y,则将一对加入链中,否则忽略它。
请注意,在这个例子中,(6,8)
恰好在 (5,8)
之前排序。当它们的 Y 值相等时,选择哪一对用于链并不重要,只要 X 值满足比之前的 Y 值大的条件即可。
这里是一个显示排序后成对数据的图表,它们以条形图形式出现在数字线上。从第一对 (2,4)
开始,每一个添加到底部的链中的对都会被着成黄色。视觉上,灰色的对被跳过是因为底部的链中已有一个黄色的对“挡住”了它被放入链中(存在值重叠)。
证明: 唯一能够将更多对加入到链中的方法是,用一个 Y 值较小的对来替换一个对,以便下一个对可以具有较小的 X 值,从而可能适合在之前无法适应的位置放置另一对。如果您使用具有相同 Y 值的对进行替换,则不会获得任何好处。如果替换具有较大的 Y 值,则所有您所做的就是可能阻止一些之前适合的对。
由于成对数据已按 Y 值排序,因此您永远不会找到比更小的 Y 值更小的替代品。向“前”查看排序后的对,它们都将具有相同或更大的 Y 值。向“后”查看时,最初从链中消除的任何对都是因为 X 值不够高,这仍然是情况。
我认为最长链的一个特征是它最小化了任何相邻元组的总跨度(以最大化任何范围内可能的元组数量)。
在这种情况下,正如Brian Stephens所建议的那样,我们只需要按第二个数字升序排序(以保证在搜索下一个元组时具有最小跨度),并从排序列表中的第一个元组开始构建链。
我们可以通过假设S(0)是从第一个元组开始的链来证明这个解决方案是最优的,存在一个S(i),其中i不在S(0)中,比S(0)更长;因此也存在一个比S(1)更长的链S(i+1)。我们知道i的开始必须在i-1的结束之前,否则它将被包含在S(0)中。现在,如果i-1的结束等于i的结束,S(i+1)将成为S(0)的一部分,这与我们的前提相矛盾。或者,如果i的结束大于i-1的结束,再次S(i+1)将被包含在S(0)中。由于列表按此属性排序,因此i的结束不能小于i-1的结束。