Algorithm 用最小数覆盖N组连续整数

Algorithm 用最小数覆盖N组连续整数,algorithm,Algorithm,我们得到N组连续整数。每个这样的集合由两个数字定义。例:2,5表示包含2,3,4,5的集合。我们必须打印要选择的最小编号,以覆盖所有N组。如果一套物品包含在一套物品中,则称一个编号涵盖了一套物品。 例:给定集合[2,5],[3,4],[10100]。例如,我们可以选择{3,10},所以我们覆盖了所有3个集合。因此答案是2 我找不到适用于N的合适算法。请注意,以下是一个贪心算法,不起作用。请参见注释。我把它留在这里,以防它对其他人有帮助 我将使用递归算法来处理这个问题。首先,请注意,如果集合不相交

我们得到N组连续整数。每个这样的集合由两个数字定义。例:2,5表示包含2,3,4,5的集合。我们必须打印要选择的最小编号,以覆盖所有N组。如果一套物品包含在一套物品中,则称一个编号涵盖了一套物品。 例:给定集合[2,5],[3,4],[10100]。例如,我们可以选择{3,10},所以我们覆盖了所有3个集合。因此答案是2


我找不到适用于N的合适算法。请注意,以下是一个贪心算法,不起作用。请参见注释。我把它留在这里,以防它对其他人有帮助

我将使用递归算法来处理这个问题。首先,请注意,如果集合不相交,则需要n个数字。第二,覆盖点集可以是集合的端点,因此这减少了选项的数量

您可以迭代/递归完成此过程。以下是算法的高级示意图:

一个迭代步骤是:

从所有集合中提取端点 计算每个端点覆盖的集合数 选择覆盖范围最大的端点 如果最大覆盖率为1,则从每个集合中选择任意点

否则,选择覆盖率最大的端点。如果最大值有限制,则任意选择一个。我不相信有关系会有什么不同

删除端点覆盖的所有集合,并将端点添加到覆盖点

重复此过程,直到没有剩余集或最大覆盖率为1。

以下是解决此问题的Onlogn方法:

按最后一个元素对集合排序例如,您的示例将被排序为[3,4]、[2,5]、[10100]。 选择第一个间隔的结尾 删除所有相交集 如果存在未覆盖的集合,则返回到2。 示例基于您的示例:

排序-集合列表按l=[3,4]、[2,5]、[10100]排序 选择4 移除覆盖集,现在就有了l=[10100] 返回到2-选择100 从列表中删除最后一个条目l=[] 到达Stop子句后,您将获得两点:4100。 @j_random_hacker的正确性证明指南:

排序范围[i,j]之后的第一个元素必须是 包括在答案中,否则该范围将不包括在内。它的 最右边的元素j至少覆盖与任何元素相同的范围集 [i,j]中的其他元素。为什么?相反,假设有 某个元素k
你的意思是连续吗?@benji:是的,我的意思是连续。它读的是连续的,我想也是不正确的连续是正确的单词。连续性在这里是没有意义的。关系是重要的:考虑问题实例{[1,2],[2,3],[3,3],[1,1] }。{1,2,3}中的任何一个覆盖了2个范围,但是如果选择了2个,则需要另外2个数字,而如果选择了1或3个,则只需要另外1个数字。除了@j_random_hacker comment之外,它实际上更尖锐,而且该算法是次优的。考虑[1,2],[3,4],[4,5],[2,5],[5,6],[5,8],[6,7],[8,9]。最受关注的终点是5条无领带。然而,如果你碰巧选择了它,你将需要再选择至少4个点,总共5个点,而最佳的解决方案是{2,4,6,8}@amit击败我几秒钟,找到一个通用的反例!这是我的:对于问题实例{[1,2],[1,3],[2,3],[3,4],[3,5],[4,5]},最优解是{2,4}。这两个数字各自仅涵盖3个范围。您的算法最初会选择3,因为它涵盖4个范围,但这将导致次优解决方案,因为还需要2个数字。最佳性证明草图:排序范围[i,j]后的第一个元素必须包含在答案中,否则该范围将不被涵盖。其最右边的元素j至少覆盖与[i,j]中任何其他元素相同的范围集。为什么?相反,假设有一个元素k