GCD = 1 인 가장 작은 부분 집합의 크기 찾기


10

이것은 폴란드 대학 프로그래밍 콘테스트 2012 연습 세션에서 발생하는 문제입니다 . 주요 콘테스트의 솔루션을 찾을 수는 있지만이 문제에 대한 솔루션을 어디에서나 찾을 수없는 것 같습니다.

문제는 다음의 세트를 가지는 보다 크지 않은 별개의 양의 정수 사이즈 찾아 1 이외의 공약수가없는 작은 서브 세트의 이고 최대 500 및 용액 존재한다고 가정 할 수있다 .N109mN

나는 을 보여주었습니다 . 나의 추론은 다음과 같습니다한다고 가정은 최소한의 부분 집합이 존재 사이즈의 , GCD와 = 1. 다음의 모든 9 집합 있어야합니다 GCD> 1.이 정확히 10 개 등의 부분 집합은, 그들의 gcds이어야 페어를 코 프라임. 이 를 i <neq j에 대해 . 여기서 입니다. 그런 다음 S 의 최대 숫자 는 g_2g_3 ... g_ {10} 입니다. 그러나 g_2g_3 ... g_ {10} \ ge 3 \ times5 \ times7 \ times11 \ times ... \ times29 = 3234846615> 10 ^ 9 , 모순입니다.m9S|S|=10S1<g1<g2<...<g10i j S g 2 g 3 . . . g 10 g 2 g 3 . . . g 103 × 5 × 7 × 11 × . . .gcd(gi,gj)=1ijSg2g3...g10g2g3...g103×5×7×11×...×29=3234846615>109

그러나 이것에도 불구하고 직접적인 무차별 대입은 여전히 ​​너무 느립니다. 다른 아이디어가 있습니까?


Whay는 할 수 없습니까? g2=2
vonbrand

g2>g12 입니다. 9 개 하위 집합의 gcd는 1이 될 수 없으므로 은 1이 될 수 없습니다.g1
Wakaka

답변:


1

이 문제는 다음과 같으며 두 가지 방법으로 축소를 구성하는 것은 쉽지 않습니다.

비트 벡터 목록이 주어지면 최소 벡터 수를 찾아 and모두 비트 벡터가되도록합니다. ( )0()

그런 다음 세트 커버 축소를 합니다. 집합 표지로, 세트 목록이 주어지면 조합을 포함하는 최소 집합 수를 찾으십시오.S 1 , , S k()S1,,Sk

세트의 요소를 합니다. 하자 , 여기서 의 경우 , 그렇지 않으면 0. 이 함수는 bijection이므로 역수입니다. F ( S ) = ( 1 - χ 1 ( S ) , ... , 1 - χ N ( S ) ) χ X ( S ) = 1 X S를a1,,anf(S)=(1χa1(S),,1χan(S))χx(S)=1xS

이제 에서 를 해결책이 이면 은 표지를 설정하는 솔루션입니다.(F) ( S (1) ) , ... , F ( S의 K ) { F ( S B 1 ) , ... , F ( S의 B의 m ) } { F - 1 ( S B 1 ) , ... , F - 1 ( S b m ) }()f(S1),,f(Sk){f(Sb1),,f(Sbm)}{f1(Sb1),,f1(Sbm)}

따라서이 문제는 검색 공간을 정리하는 능력을 테스트한다고 생각합니다.


최소 정점 커버를 어떻게 찾습니까?
Yuval Filmus

오,이 솔루션은 대신 커버를 설정합니다.
Chao Xu

1
사실이지만,이 특별한 경우의 특정 속성을 활용할 수 있다고 생각합니다. 예를 들어,이 경우 세트는 이상의 크기로 모두 매우 큽니다 . 실제로 세트의 숫자가 모두 작 으면 크기가 더 커집니다. 또한 모든 것을 다루는 9 세트를 확실히 찾을 수 있습니다. 어쨌든 검색 공간을 정리하는 방법은 무엇입니까? n9
Wakaka

문제 (*)가 질문에 주어진 것과 어떻게 같은지 알 수 없습니다. 우선, 질문에 주어진 문제는 모든 정수가 일 것이라고 약속합니다 . 이는 문제에 나타나지 않는 비트 벡터의 가중치에 대한 보증에 해당합니다 (*). 109
DW

1

모든 pairwise gcd를 계산하고 중복을 제거한 다음 재귀를 통해 비교적 효율적으로 해결할 수 있습니다. 재귀하기 전에 중복을 제거하여 효율적으로 만드는 작업입니다.

아래에서 알고리즘을 자세히 설명하지만 먼저 이진 연산자 를 정의하는 데 도움이됩니다 . 경우 양의 정수의 집합은 정의입니다S , TS,T

ST={gcd(s,t):sS,tT}.

그 주및 (문제가 있음); 일반적으로 는 제안 된 범위보다 훨씬 작으므로 알고리즘을 효율적으로 만드는 데 도움이됩니다. 또한 를 계산할 수 있습니다. 간단한 열거에 의한 gcd 연산.| S T | 10 9 S T S T | S | × | T ||ST||S|×|T||ST|109STST|S|×|T|

이 표기법으로 알고리즘은 다음과 같습니다. 하자 번호의 입력 설정합니다. 계산 , 다음 , 다음 , 등등. 이지만 과 같은 가장 작은 찾으십시오 . 그런 다음 가장 작은 하위 집합의 크기는 입니다. 이러한 하위 집합의 구체적인 예를 출력하려는 ​​경우 백 포인터를 유지하면 이러한 집합을 쉽게 재구성 할 수 있습니다.S 2 = S 1S 1 S 3 = S 1S 2 S 4 = S 1S 3 k 1 S k 1 S k 1 kS1S2=S1S1S3=S1S2S4=S1S3k1Sk1Sk1k

중간 집합의 크기가 이상으로 실제로 크기가 그보다 훨씬 작을 것이므로) 실행 시간이 약 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 1S 1 S 4 = S 2S 2 Sk1SkxSiS1xiS1,S2,S3,S4,,S9S1,S2,S4,S8,S9S2=S1S1S4=S2S2S (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=S4S4 , . 가면서 와 같은 첫 번째 . 와 같은 발견 하면 즉시 중지 할 수 있습니다 . 과 관련된 하위 집합을 보면 gcd가 인 가장 작은 하위 집합을 찾을 수 있습니다 . 따라서 와 같이 세트 도달하자마자 중지 할 수 있으므로 더 작은 하위 집합을 찾으면 조기에 중지 할 수 있습니다.S9=S1×S8k[1,2,4,8,9]1Skk1Sk11Sk1Sk

이것은 시간 효율적이고 공간 효율적이어야합니다. 공간을 절약하기 위해 각 요소 에 대해 전체 세트를 저장할 필요는 없습니다. 두 개의 백 포인터를 저장하는 것으로 충분합니다 (그래서 gcd를 가져간 의 두 요소는 를 얻음 ). 선택적으로 해당 서브 세트의 크기.S i , S j xxSkSi,Sjx

원칙적으로, 시퀀스 를 다른 첨가 체인으로 대체 할 수 있습니다 . 다른 추가 체인이 더 나을지 모르겠습니다. 최적의 선택은 정답의 분포와 세트 의 예상 크기에 따라 . 이는 분명하지 않지만 실험을 통해 실험적으로 도출 될 수 있습니다.S k[1,2,4,8,9]Sk

크레딧 : 각 요소와 함께 숫자의 하위 집합을 저장하는 아이디어를 제공 한 KWillet에게 감사드립니다 .Si


바이너리 검색이 필요하지 않다고 생각합니다. 각 gcd와 함께 요소 수를 저장하고 두 배가되는 동안 최소 쌍 합계로 설정할 수 있습니다.
KWillets

좋은 점, @KWillets! 그 아름다운 생각에 감사합니다! 나는 그것을 내 대답에 포함시켰다.
DW

0

아마도 다른 방법으로 이것을 보는 것이 더 빠를 것입니다 ... 보다 작은 최대 소수 는 31607이며, 2와 31607 사이의 총 3401 소수는 많지 않습니다. 소수에 대해 최대 31607까지 완전하게 인수 분해 된 각 숫자를 씁니다. 여기에서 는 1 또는 큰 소수입니다. 그러면 대응하는 벡터가 선형으로 독립적이고 (및 가 다르거 나 1 인 경우) 집합 이 상대적으로 소수 이며 행렬 의 순위 를 찾고 있습니다. ai=p n i 1 1 p n i 2 2PiPiainijP109

ai=p1ni1p2ni2Pi
PiainijP

선형 독립성과 어떤 관련이 있습니까? 벡터 ( 1 , 0 ) 은 선형 적으로 독립적이지만 GCD는 ( 1 , 0 ) 이고 ( 0 , 0 ) 원합니다 . (1,1)(1,0)(1,0)(0,0)
Yuval Filmus

1
선형 독립성은 작동하지 않는 것 같지만이 주요 분해를 다른 방식으로 사용할 수 있습니다. 각각의 주요 내용은 (가운데 3401 페이지 의와는 최대 500 P 내가 '들), 세트 정의 페이지 가없는 모든 숫자의 집합으로 (지정된 세트 중에서) 페이지를 요인으로합니다. 문제는 이제 작은 부분 집합 찾을 수 있습니다 B 번호 등의를 각에 대한 P , | A pB | 1 . 이것은 세트 커버 문제와 동등한 타격 세트 문제입니다. 이것은 N P입니다p3401 pi500 PiAppBAp|ApB|1NP-완료되었지만이 크기에 충분히 빠른 구현이있을 수 있습니다.
polkjh

작동 할 수있는 구현으로 안내 할 수 있습니까? 지금까지는 근사 알고리즘 만 찾을 수 있습니다. 감사!
Wakaka

설문지 는 대략적인 솔루션과 정확한 솔루션을 모두 살펴 봅니다. 댓글에 답장을 보내려면 댓글에 @ name-of-person을 추가하십시오. 해당 사람에게 알림을 보냅니다. 그렇지 않으면 그들은 당신의 의견에 대해 전혀 알지 못할 수도 있습니다.
polkjh

-1

gcd (S) = 1 인 부분 집합을 찾을 수 있다면 gcd (S) = 1 인 2 개의 요소 만 남을 때까지 항상 부분 집합에서 중복 요소를 제거 할 수 있습니다. 하위 집합에 2 개의 요소가 포함되거나 존재하지 않습니다.

이제이 문제를 해결하기 위해 재귀를 사용합니다. 숫자 배열을 n-1 요소가있는 요소와 1 요소 (마지막 요소)가있는 두 부분으로 나눕니다. 두 숫자는 첫 번째 n-1 요소에 있거나 하나의 요소는 첫 번째 요소에서 마지막 요소와 쌍을 이루게됩니다. 따라서 우리는이 문제를 해결할 수 있습니다

T (n) = T (n-1) + O (n) 시간. 이는 T (n) = O (n ^ 2)를 의미합니다.


4
입니다. 어떤 요소를 제거 할 수 있습니까? gcd(6,10,15)=1
Rick Decker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.