Думаю, у меня есть алгоритм O(n lg U)
для этого, где U
- наибольшее число. Идея похожа на идею user949300, но с немного более подробной информацией.
Интуиция такова. Когда вы объединяете два числа вместе, чтобы получить максимальное значение, вы хотите иметь 1
в наивысшей возможной позиции, а затем из пар, которые имеют 1
в этой позиции, вам нужно объединить в пару с 1
в следующей возможное наивысшее положение и т. д.
Итак, алгоритм следующий. Начните с поиска самого высокого 1
бита в любом месте чисел (вы можете сделать это вовремя O(n lg U)
, выполнив O(lg U)
работу для каждого из n
чисел). Теперь разделите массив на две части - одно из чисел с 1
в этом бите и группу с 0
в этом бите. Любое оптимальное решение должно сочетать число с 1
в первом месте с числом с 0
в этом месте, поскольку в этом случае бит 1
будет максимально высоким. Любая другая пара имеет там 0
.
Теперь рекурсивно мы хотим найти пару чисел из группы 1
и 0
, которая имеет наивысшее значение 1
. Для этого из этих двух групп разделите их на четыре группы:
- Числа, начинающиеся с
11
- Числа, начинающиеся с
10
- Числа, начинающиеся с
01
- Числа, начинающиеся с
00
Если есть какие-либо числа в группе 11
и 00
или в группах 10
и 01
, их XOR будет идеальным (начиная с 11
). Следовательно, если какая-либо из этих пар групп не пуста, рекурсивно вычислите идеальное решение из этих групп, а затем верните максимальное из этих решений подзадач. В противном случае, если обе группы пусты, это означает, что все числа должны иметь одну и ту же цифру во второй позиции. Следовательно, оптимальный XOR числа, начинающегося с 1
, и числа, начинающегося с 0
, в конечном итоге приведет к отмене следующего второго бита, поэтому мы должны просто взглянуть на третий бит.
Это дает следующий рекурсивный алгоритм, который, начиная с двух групп чисел, разделенных их старшим битом, дает ответ:
- Given group
1
and group 0
and a bit index i
:
- If the bit index is equal to the number of bits, return the XOR of the (unique) number in the
1
group and the (unique) number in the 0
group.
- Создайте группы
11
, 10
, 01
и 00
из этих групп.
- Если группа
11
и группа 00
непусты, рекурсивно найдите максимальное значение XOR для этих двух групп, начиная с бита i + 1
.
- Если группа
10
и группа 01
непусты, рекурсивно найдите максимальное значение XOR для этих двух групп, начиная с бита i + 1
.
- Если любая из вышеперечисленных пар была возможна, то верните максимальную пару, найденную рекурсией.
- В противном случае все числа должны иметь один и тот же бит в позиции
i
, поэтому верните максимальную пару, найденную, посмотрев на бит i + 1
в группах 1
и 0
.
Чтобы начать алгоритм, вы можете просто разделить числа из исходной группы на две группы - числа с MSB 1
и числа с MSB 0
. Затем вы запускаете рекурсивный вызов вышеуказанного алгоритма с двумя группами чисел.
В качестве примера рассмотрим числа 5 1 4 3 0 2
. У них есть представления
101 001 100 011 000 010
Начнем с разделения их на группу 1
и группу 0
:
101 100
001 011 000 010
Теперь применим описанный выше алгоритм. Мы разбиваем это на группы 11
, 10
, 01
и 00
:
11:
10: 101 100
01: 011 010
00: 000 001
Теперь мы не можем соединить какие-либо 11
элементы с 00
элементами, поэтому мы просто рекурсивно используем группы 10
и 01
. Это означает, что мы создаем группы 100
, 101
, 010
и 011
:
101: 101
100: 100
011: 011
010: 010
Теперь, когда мы подошли к корзинам с одним элементом в них, мы можем просто проверить пары 101
и 010
(что дает 111
) и 100
и 011
(что дает 111
). Здесь работает любой вариант, поэтому мы получаем, что оптимальный ответ 7
.
Давайте подумаем о времени работы этого алгоритма. Обратите внимание, что максимальная глубина рекурсии равна O(lg U)
, поскольку в числах всего O(log U)
бит. На каждом уровне дерева каждое число появляется ровно в одном рекурсивном вызове, и каждый из рекурсивных вызовов действительно работает пропорционально общему количеству чисел в группах 0
и 1
, потому что нам нужно распределить их по битам. Следовательно, в дереве рекурсии есть O(log U)
уровень, и каждый уровень выполняет O(n)
работу, что дает общую работу O(n log U)
.
Надеюсь это поможет! Это была потрясающая проблема!
person
templatetypedef
schedule
16.02.2012