모든 pairwise gcd를 계산하고 중복을 제거한 다음 재귀를 통해 비교적 효율적으로 해결할 수 있습니다. 재귀하기 전에 중복을 제거하여 효율적으로 만드는 작업입니다.
아래에서 알고리즘을 자세히 설명하지만 먼저 이진 연산자 를 정의하는 데 도움이됩니다 . 경우 양의 정수의 집합은 정의입니다S , T⊗에스, T
에스⊗ T= { gcd ( s , t ) : s ∈ S, t ∈ T} .
그 주및 (문제가 있음); 일반적으로 는 제안 된 범위보다 훨씬 작으므로 알고리즘을 효율적으로 만드는 데 도움이됩니다. 또한 를 계산할 수 있습니다. 간단한 열거에 의한 gcd 연산.| S ⊗ T | ≤ 10 9 S ⊗ T S ⊗ T | S | × | T || 에스⊗ T| ≤ | 에스| × | 티|| 에스⊗ T| ≤ 109에스⊗ T에스⊗ 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 k에스1에스2= S1⊗ S1에스삼= S1⊗ S2에스4= S1⊗ S삼케이1 ∈ S케이1 ∉ Sk - 1케이
중간 집합의 크기가 이상으로 실제로 크기가 그보다 훨씬 작을 것이므로) 실행 시간이 약 gcd 조작. 500 × ( | S (1) | + | S 2 | + ⋯ )109500 × ( | S1| + | 에스2| +⋯)
다음은 효율성을 더욱 향상시킬 수있는 최적화입니다. 기본적으로 반복되는 배가를 사용하여 와 같은 가장 작은 를 찾을 수 있습니다 . 특히, 각 요소 에 대해 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 S케이1 ∈ S케이x ∈ S나는에스1엑스≤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
이것은 시간 효율적이고 공간 효율적이어야합니다. 공간을 절약하기 위해 각 요소 에 대해 전체 세트를 저장할 필요는 없습니다. 두 개의 백 포인터를 저장하는 것으로 충분합니다 (그래서 gcd를 가져간 의 두 요소는 를 얻음 ). 선택적으로 해당 서브 세트의 크기.S i , S j xx∈SkSi,Sjx
원칙적으로, 시퀀스 를 다른 첨가 체인으로 대체 할 수 있습니다 . 다른 추가 체인이 더 나을지 모르겠습니다. 최적의 선택은 정답의 분포와 세트 의 예상 크기에 따라 . 이는 분명하지 않지만 실험을 통해 실험적으로 도출 될 수 있습니다.S k[1,2,4,8,9]Sk
크레딧 : 각 요소와 함께 숫자의 하위 집합을 저장하는 아이디어를 제공 한 KWillet에게 감사드립니다 .S나는