我们给出了N组连续的整数。每个这样的集合由两个数字定义。例:2,5表示含有2,3,4,5的集合。我们必须打印最小数量。要选择的数字以覆盖所有N组。一个人据说如果它包含在集合中则覆盖集合。 例如:给定集[2,5],[3,4],[10,100]。我们可以选择例如{3,10},所以我们掩盖了所有3套。因此答案是2。
我无法为N <= 5000找到合适的算法。
答案 0 :(得分:3)
这是解决问题的O(nlogn)
方法:
[3,4], [2,5] , [10,100]
)。示例(基于您的示例):
l =[3,4], [2,5] , [10,100]
l=[10,100]
l=[]
@j_random_hacker的正确性证明(指南):
第一个(排序后)范围[i,j]中的一些元素必须是 包括在答案中,或该范围不包括在内。它的 最右边的元素j至少覆盖与任何一组相同的范围 [i,j]中的其他元素。为什么?假设有相反的情况 一些元素k&lt; j涵盖了j未涵盖的范围:那么 该范围必须具有端点&lt; j,这与事实相矛盾 [i,j]具有最小的端点(我们知道这是因为它是第一个 在排序列表中)
答案 1 :(得分:1)
请注意以下是无法运行的贪婪算法(请参阅注释)。我将它留在这里,万一它可以帮助别人。
我会使用递归算法来解决这个问题。首先,请注意,如果这些集合是不相交的,那么您需要&#34; n&#34;数字。第二,&#34;覆盖&#34;点可以是集合的末尾,因此这是减少的选项数量。
您可以通过此方式迭代/递归。以下是该算法的高级草图:
一个迭代步骤是:
如果最大覆盖范围为1,则从每组中选择一个任意点。
否则,请选择覆盖范围最大的端点。如果有最大关系,任意选择一个。当有关系时,我不相信它会有所作为。
删除端点覆盖的所有集合,并将端点添加到&#34;覆盖点&#34;。
重复此过程,直到没有剩下任何设置或最大覆盖范围为1.