我将在不编程的情况下用一般语言给出解决方案。
让我们将段表示为 s 1 , s 2 , ..., s n。它们的开头为 b 1 , b 2 ,... b n,结尾为 e 1 , e 2 ,... e n。
按段的开头对段进行排序,因此 b 1 < b 2 <...< b n。如果没有三个段覆盖一个点的条件成立,检查它们就足够了。我们将按照从 b 1到 b n的顺序执行此操作。因此,从 b 1开始,移动到下一个点,以此类推,直到某个点 b i有三个段覆盖它。这些将是段 s i和另外两个段,比如说 s j和 s k。在这三个段中,删除具有最大端点的段,即 max{e i , e j , e k}。移动到下一段的开头 (b i+1 )。当我们到达 b n时,这个过程就完成了。剩下的所有线段构成最大的线段子集,因此没有三个线段共享一个公共点。
为什么这将是最大子集。假设我们的解决方案是 S(段集)。假设存在最优解 S*。再次,按照起点坐标对 S 和 S* 中的段进行排序。现在,我们将遍历 S 和 S* 中的段并比较它们的端点。通过为 S 中的任何第 k 段构造 S,其结束坐标小于S* 中第 k 段的结束坐标(ek < = ek )。因此,S 中的段数不少于 S(在 S* 中移动,我们总是超过 S)。
如果这还不够令人信服,请先尝试考虑一个更简单的问题,即没有两个片段可以重叠。解决方案是相同的,但更直观地了解为什么它给出了正确的答案。