我给了n个数字a_1,a_2,...,a_n
并且它们被给予两个me in和非递减序列,这意味着数组中的a_1<=a_2<=...<=a_n
并且我可以将其中两个配对,比如说a_i
和a_j
当且仅当2a_i <= a_j
。我可以最大限度地进行多少不相交的配对?
我在这里完全失败了。我试图贪婪地做。假设我将最大的一个与最小的一个配对,从序列中删除它们并递归地进行。但这是错误的,因为对于1,2,3,8
我会得到一对(1,8)
,但我可以制作两对(1,2)
和(3,8)
。基于这个反例,我尝试以不同的方式解决它。假设我将a_i
与我能够的第一个号码配对。然后就是这个反例1,3,4,6
。我会再次获得一对(1,3)
,但实际上我可以制作两对(1,4)
和(3,6)
。
有人能给我一些关于如何进行的暗示吗?
我认为以下n元素表会很有用。元素a_1,...,a_n
tab[j]
表示2a_i
小于a_j
的元素数。该表可以在O(n)
时间内简单计算。但我不知道如何正确使用它。
答案 0 :(得分:4)
观察最好的情况是你可以在中间分割数组并将前半部分与后半部分相匹配,因此最大可能的答案是 n / 2 。
1 2 3 4 | 5 6 7 8
1 -> 5
2 -> 6
3 -> 7
4 -> 8
我们可以证明,如果存在 k 分配的解决方案,可以通过将 a i 与 a配对来完成 n - k + i 所有1≤i≤k:
1 2 5 | 6 7 | 8 9 10
1 -> 8
2 -> 9
5 -> 10
我们还可以证明,如果存在k≥1分配的解决方案,则还存在具有 k - 1 分配的解决方案。因此,我们可以二进制搜索最大的 k 并使用贪婪的赋值来检查实际上是否可以在每个步骤中进行一定数量的赋值。
运行时: O(n log n)
UPDATE (由于用户interjay):从我们上面假设的情况来看,我们也可以贪婪地将前半部分中的元素按递增顺序分配给第一个未分配的元素。下半场。我们可以通过维护指向前一个分配的后半部分中的元素的指针来实现。运行时: O(n)