すべてのペアワイズgcdを計算し、重複を削除してから再帰することで、これを比較的効率的に解決できます。再帰する前に重複を削除することで効率的になります。
アルゴリズムについては以下で詳しく説明しますが、最初に、二項演算子を定義すると役立ちます。場合は正の整数の集合である、定義S 、T⊗S,T
S⊗T={gcd(s,t):s∈S,t∈T}.
ことに注意してくださいおよび(問題中); 通常、は、これらの境界のどちらかが示唆するよりもさらに小さくなり、アルゴリズムの効率化に役立ちます。でを計算できることにも注意してください単純な列挙によるgcd操作。| S ⊗ T | ≤ 10 9 S ⊗ T S ⊗ T | S | × | T ||S⊗T|≤|S|×|T||S⊗T|≤109S⊗TS⊗T|S|×|T|
その表記で、これがアルゴリズムです。してみましょう数字の入力集合とします。計算、その後、、その後、、というように。だがような最小のを見つける。次に、そのような最小のサブセットのサイズがであることを知っています。そのようなサブセットの具体的な例も出力したい場合は、バックポインターを保持することで、そのようなセットを簡単に再構築できます。S 2 = S 1 ⊗ S 1 S 3 = S 1 ⊗ S 2 S 4 = S 1 ⊗ S 3、K 1 ∈ S K 1 ∉ S K - 1 KS1S2=S1⊗S1S3=S1⊗S2S4=S1⊗S3k1∈Sk1∉Sk−1k
中間セットのサイズが超えることはなく(実際、それらのサイズはおそらくそれよりはるかに小さいため)、実行時間は約必要ですこれは比較的効率的です。 gcd操作。 500 × (| S 1 | + | S 2 | + ⋯ )109500×(|S1|+|S2|+⋯)
これは、効率をさらに向上させる可能性のある最適化です。基本的に、反復ダブリングを使用して、ような最小のを見つけることができます。特に、各要素について、gcdがでサイズがであるの最小サブセットを追跡します。(重複を削除すると、小さい方のサブセットを優先してタイを解決します。)ここで、9つのセットのシーケンスを計算する代わりに、代わりに5つのセットのシーケンスを計算します。、計算することにより、、次に1 ∈ S K X ∈ S I S 1のx ≤ iがS 1、S 2、S 3、S 4、... 、S 9 S 1、S 2、S 4、S 8、S 9 S 2 = S 1 ⊗ S 1 、S 4 = S 2 ⊗ S 2 Sk1∈Skx∈SiS1x≤iS1,S2,S3,S4,…,S9S1,S2,S4,S8,S9S2=S1⊗S1S4=S2⊗S2S 9 = S 1 × S 8のk ∈ [ 1 、2 、4 、8 、9 ] 1 ∈ S K K 1 ∈ S K 1 1 S K 1 ∈ S KS8=S4⊗S4、次に。進むにつれて、なる最初のます。となるようなを見つけたら、すぐに停止できます関連付けられているサブセットを調べると、gcdがである最小のサブセットを見つけることができます。そのため、がになるようなセット達したらすぐに停止できます。これにより、小さいサブセットが見つかった場合に早期に停止できます。S9=S1×S8k∈[1,2,4,8,9]1∈Skk1∈Sk11Sk1∈Sk
これは、時間効率とスペース効率に優れている必要があります。スペースを節約するには、各要素、セット全体を格納する必要はありません。2つのバックポインタを格納するだけで十分です(を取得するには、gcdを実行した 2つの要素)。オプションで、対応するサブセットのサイズ。S I、S jの Xx∈SkSi,Sjx
原則として、シーケンスを他の追加チェーンで置き換えることができます。他の追加チェーンの方が優れているかどうかはわかりません。最適な選択は、正解の分布とセット予想されるサイズに依存する可能性があります。S K[1,2,4,8,9]Sk
クレジット:の各要素と一緒に数字のサブセットを格納するためのアイデアKWilletsに感謝早く停止することができます。Si