Algorithm 覆盖从0到n的所有整数的最小对数

Algorithm 覆盖从0到n的所有整数的最小对数,algorithm,language-agnostic,Algorithm,Language Agnostic,我在一次编程竞赛中遇到了这个问题,但解决不了 给定一个0到n的范围,以及以下格式给出的一些数字对: a1 b1 a2 b2 a3 b3 . . . . am bm 其中:0这就是我应该怎么做的,我相信它在O(n^2)时间内运行 让我们使用集合抽象。将每一对映射到它覆盖的一组整数。这是a和b之间的比较。所以对于n=6,(1,5)={1,2,3,4,5},(3,1)={0,1,3,4,5,6} 然后我们要覆盖一组从0到n的整数。称之为G(目标) 使用贪心方法,我们迭代从对生成的所有集合,并找到与G

我在一次编程竞赛中遇到了这个问题,但解决不了

给定一个0到n的范围,以及以下格式给出的一些数字对:

a1 b1
a2 b2
a3 b3
. .
. .
am bm

其中:
0这就是我应该怎么做的,我相信它在O(n^2)时间内运行

让我们使用集合抽象。将每一对映射到它覆盖的一组整数。这是a和b之间的比较。所以对于
n=6
(1,5)={1,2,3,4,5}
(3,1)={0,1,3,4,5,6}

然后我们要覆盖一组从0到n的整数。称之为G(目标)

使用贪心方法,我们迭代从对生成的所有集合,并找到与G相交元素最多的集合。从G中删除这些元素,并将1添加到计数器中

使用for循环进行迭代,并在没有更多元素时完成。或者返回-1,当某个特定迭代的任何集合都不会从交点生成更多元素时


每次迭代时,我们都会减小目标集的大小,并选择覆盖剩余元素大部分数量的一对。因此,当我们完成时,可以保证最小值。

我相信下面的贪婪算法应该可以工作

首先,按
x
对对
(x,y)
进行排序(您可以将
x>y
对拆分为
[0,y]
[x,n]
)。现在,选择第一个,并将指针
current
设置为第一个间隔


然后,将
current
指针移动到带有
x1和pairs[i]的pairs。x如何生成pairs?或者您可以自己定义配对(因为我们希望找到最小值)。我可能误解了这个问题,因为如果我可以生成自己的对,那么(0,n)将涵盖所有内容,不是吗?还有,你的意思是在第二种情况下a_i到n和0到b_i?由于a_i>b_i.No给出了这些对,因此也有可能它们都不能覆盖整个范围0到n,在这种情况下,答案是-1。我是否缺少smt?对于(3,1),它覆盖了0到3,1到n,所以所有的都覆盖了?@Phamtrong是的,你是对的,我的错,打字错误。我编辑了这个问题。(3,1)不能覆盖2。一个数字可以覆盖多次,还是覆盖必须恰好覆盖每个数字一次?e、 g.0,50和40100是否覆盖范围0到100?这是否适用于ai>bi范围?@Peterderiveaz您可以将它们分成两对
[0 bi],[ai,n]
,,所以,如果它能起作用,那么它也适用于那些。但是,如果我们最终使用这两个对,那么你的方法不会认为这2对是成本2的吗?你需要跟踪这样的分裂对,因为我们最终需要成对的数量。PeterdeRivaz好吧,如果使用任何这样的对,跟踪应该很容易,因为该算法以增量方式生成所选对的集合。如果我们选择了
k
这样的对,请确保只将它们计算为
floor((k+1)/2)
1 3
3 7
3 4
4 9
4 10
4 8
5 9
1 3
3 7
1 3
3 7
4 10
=> [1 10] covered
# after the sort
pick first
for i = 1 to len(given pairs):
  if pairs[i].x <= picked[-1].y and pairs[i].y > picked[-1].y:
    if len(picked) > 1 and pairs[i].x <= picked[-2].y:
      picked[-1] = pairs[i]
    else:
      picked.append(pairs[i])