Это можно решить относительно эффективно путем вычисления всех парных gcd, удаления дубликатов, а затем повторения. Это действие по удалению дубликатов, прежде чем вы начнете повторять, что делает его эффективным.
Я объясню алгоритм более подробно ниже, но сначала он помогает определить бинарный оператор . Если - наборы натуральных чисел, определите⊗S,T
S⊗T={gcd(s,t):s∈S,t∈T}.
Обратите внимание, чтои (в вашей задаче); обычно будет даже меньше, чем предполагает любая из этих границ, что помогает сделать алгоритм эффективным. Также обратите внимание, что мы можем вычислить с помощьюОперации gcd простым перечислением.|S⊗T|≤|S|×|T||S⊗T|≤109S⊗TS⊗T|S|×|T|
С этим обозначением вот алгоритм. Пусть будет входным набором чисел. Вычислить , затем , затем и так далее. Найдите наименьшее такое, что но . Тогда вы знаете, что размер наименьшего такого подмножества равен . Если вы также хотите вывести конкретный пример такого подмножества, сохраняя обратные указатели, вы можете легко восстановить такой набор.S1S2=S1⊗S1S3=S1⊗S2S4=S1⊗S3k1∈Sk1∉Sk−1k
Это будет относительно эффективно, так как ни один из промежуточных наборов не увеличится в размерах выше (на самом деле их размер, вероятно, будет намного меньше этого размера), а время выполнения требует около операции gcd.109500×(|S1|+|S2|+⋯)
Вот оптимизация, которая может повысить эффективность еще больше. В принципе, вы можете использовать повторное удвоение, чтобы найти наименьшее такое, что . В частности, для каждого элемента мы отслеживаем наименьшее подмножество чей gcd равен а размер равен . (Когда вы удаляете дубликаты, вы разрешаете связи в пользу меньшего подмножества.) Теперь вместо того, чтобы вычислять последовательность из девяти наборов , мы вместо этого вычисляем последовательность из пяти наборов , вычисляя , затем , затемk1∈Skx∈SiS1x≤iS1,S2,S3,S4,…,S9S1,S2,S4,S8,S9S2=S1⊗S1S4=S2⊗S2S8=S4⊗S4 , затем . На ходу найдите первый такой, что . Как только вы нашли такое, что , вы можете немедленно остановиться: вы можете найти наименьшее подмножество, чей gcd равен , посмотрев на подмножество, связанное с . Таким образом, вы можете остановиться, как только достигнете набора такого, что , что позволяет останавливаться раньше, если вы найдете меньшее подмножество.S9=S1×S8k∈[1,2,4,8,9]1∈Skk1∈Sk11Sk1∈Sk
Это должно быть эффективным с точки зрения времени и пространства. Чтобы сэкономить место, для каждого элемента вам не нужно хранить весь набор: достаточно сохранить два обратных указателя (поэтому два элемента , из которых вы взяли gcd, чтобы получить ) и необязательно размер соответствующего подмножества.x∈SkSi,Sjx
В принципе, вы можете заменить последовательность на любую другую цепочку добавления . Я не знаю, будет ли какая-то другая цепочка дополнений лучше. Оптимальный выбор может зависеть от распределения правильных ответов и ожидаемых размеров наборов , что мне не ясно, но, вероятно, может быть получено опытным путем с помощью экспериментов.[1,2,4,8,9]Sk
Благодарности: Моя благодарность KWillets за идею сохранения подмножества чисел вместе с каждым элементом , что позволяет рано останавливаться.Si