用最少的nos覆盖N组连续的整数

时间:2014-12-07 22:06:40

标签: algorithm

我们给出了N组连续的整数。每个这样的集合由两个数字定义。例:2,5表示含有2,3,4,5的集合。我们必须打印最小数量。要选择的数字以覆盖所有N组。一个人据说如果它包含在集合中则覆盖集合。 例如:给定集[2,5],[3,4],[10,100]。我们可以选择例如{3,10},所以我们掩盖了所有3套。因此答案是2。

我无法为N <= 5000找到合适的算法。

2 个答案:

答案 0 :(得分:3)

这是解决问题的O(nlogn)方法:

  1. 按最后一个元素对集合进行排序(例如,您的示例将排序为[3,4], [2,5] , [10,100])。
  2. 选择第一个间隔的结束
  3. 删除所有相交的集合
  4. 如果有一些未覆盖的设置,请返回2.
  5. 示例(基于您的示例):

    1. 排序 - 您的集合列表按l =[3,4], [2,5] , [10,100]
    2. 排序
    3. 选择4
    4. 删除已涵盖的集合,您现在拥有l=[10,100]
    5. 返回2 - 选择100
    6. 从列表l=[]
    7. 中删除最后一个条目
    8. 达到了停止条款,你完成了两点:4,100。
    9. @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.