Algorithm 覆盖从0到n的所有整数的最小对数
我在一次编程竞赛中遇到了这个问题,但解决不了 给定一个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
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])