Jest to problem z sesji treningowej Polskiego Konkursu Programowania Uczelnianego 2012 . Chociaż mogłem znaleźć rozwiązania dla głównego konkursu, nie mogę nigdzie znaleźć rozwiązania tego problemu.
Problem polega na tym: biorąc pod uwagę zbiór wyraźnych liczb całkowitych dodatnich nie większych niż , znajdź rozmiar najmniejszego podzbioru, który nie ma wspólnego dzielnika innego niż 1. wynosi co najwyżej 500 i można założyć, że istnieje rozwiązanie . m N
Udało mi się pokazać, że . Moje rozumowanie jest następujące: załóżmy, że istnieje minimalny podzbiór o rozmiarze , z gcd = 1. Wtedy wszystkie 9-podzbiorów musi mieć gcd> 1. Istnieje dokładnie 10 takich podzbiorów, a ich gcds muszą być parami coprime. Niech te gcds będą wynosić , gdzie , dla i \ neq j . Zatem maksymalna liczba w S to g_2g_3 ... g_ {10} . Ale g_2g_3 ... g_ {10} \ ge 3 \ times5 \ times7 \ times11 \ times ... \ times29 = 3234846615> 10 ^ 9 , sprzeczność.
Jednak nawet przy tym bezpośrednia brutalna siła jest wciąż zbyt wolna. Czy ktoś ma jakieś inne pomysły?
źródło
Odpowiedzi:
Ten problem jest równoważny z poniższym, a budowanie redukcji w obie strony jest banalne.
Biorąc pod uwagę listę wektorów bitowych, znajdź ich minimalną liczbę, tak aby0 (∗)
and
wszystkie uzyskały wektor bitów. ( ∗ )Następnie pokazujemy, że zestaw ochrony zmniejsza się do . Przez zestaw okładek rozumiem, biorąc pod uwagę listę zestawów , znajdź minimalną liczbę zestawów, która pokrywa ich związek.S 1 , … , S k(∗) S1,…,Sk
Zamawiamy elementy w zestawach na . Niech , gdzie jeśli , 0 w przeciwnym razie. Zauważ, że ta funkcja jest bijectcją, więc ma odwrotność.a1,…,an f(S)=(1−χa1(S),…,1−χan(S)) χx(S)=1 x∈S
Teraz, jeśli rozwiążemy na , a rozwiązaniem jest , to to rozwiązanie zapewniające ochronę.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)} {f−1(Sb1),…,f−1(Sbm)}
Myślę więc, że ten problem polega na sprawdzeniu czyjejś umiejętności przycinania przestrzeni wyszukiwania.
źródło
Jest to względnie wydajne rozwiązanie, obliczając wszystkie pary gcd, usuwając duplikaty, a następnie rekursując. To czynność polegająca na usuwaniu duplikatów przed ponownym użyciem sprawia, że jest to wydajne.
Wyjaśnię algorytm bardziej szczegółowo poniżej, ale najpierw pomaga zdefiniować operator binarny . Jeśli S , T są zestawami liczb całkowitych dodatnich, zdefiniuj⊗ S,T
Zauważ, że i | S ⊗ T | ≤ 10 9 (w twoim problemie); zazwyczaj S ⊗ T będzie nawet mniejszy niż sugeruje jedna z tych granic, co pomaga zwiększyć efektywność algorytmu. Zauważ też, że możemy obliczyć S ⊗ T za pomocą | S | × | T | operacje gcd przez proste wyliczenie.|S⊗T|≤|S|×|T| |S⊗T|≤109 S⊗T S⊗T |S|×|T|
Przy tej notacji oto algorytm. Niech będzie wejściowym zestawem liczb. Oblicz S 2 = S 1 ⊗ S 1 , następnie S 3 = S 1 ⊗ S 2 , następnie S 4 = S 1 ⊗ S 3 i tak dalej. Znajdź najmniejszy k taki, że 1 ∈ S k ale 1 ∉ S k - 1 . Wtedy wiesz, że rozmiar najmniejszego takiego podzbioru wynosi kS1 S2=S1⊗S1 S3=S1⊗S2 S4=S1⊗S3 k 1∈Sk 1∉Sk−1 k . Jeśli chcesz również przedstawić konkretny przykład takiego podzbioru, zachowując wskaźniki wsteczne, możesz łatwo zrekonstruować taki zestaw.
Będzie to stosunkowo wydajne, ponieważ żaden z zestawów pośrednich nie wzrośnie powyżej (w rzeczywistości ich rozmiar prawdopodobnie będzie znacznie mniejszy niż ten), a czas działania wymaga około 500 × ( | S 1 | + | S 2 | + ⋯ ) operacje gcd.109 500×(|S1|+|S2|+⋯)
Oto optymalizacja, która może jeszcze bardziej poprawić wydajność. Zasadniczo możesz użyć iterowanego podwajania, aby znaleźć najmniejsze takie jak 1 ∈ S k . W szczególności dla każdego elementu x ∈ S i śledzimy najmniejszy podzbiór S 1, którego gcd wynosi x i którego rozmiar wynosi ≤ i . (Kiedy usuwasz duplikaty, rozwiązujesz powiązania na korzyść mniejszego podzbioru.) Teraz zamiast obliczać sekwencję dziewięciu zestawów S 1 , S 2 , S 3 , S 4 ,k 1∈Sk x∈Si S1 x ≤i , zamiast tego obliczamy sekwencję pięciu zestawów S 1 , S 2 , S 4 , S 8 , S 9 , obliczając S 2 = S 1 ⊗ S 1 , następnie S 4 = S 2 ⊗ S 2 , a następnie S 8 = S 4 ⊗ S 4 , a następnie S 9 = S 1 × S 8S1,S2,S3,S4,…,S9 S1,S2,S4,S8,S9 S2=S1⊗S1 S4=S2⊗S2 S8=S4⊗S4 S9=S1×S8 . Idąc, znajdź pierwszą taką, że 1 ∈ S k . Po znalezieniu k takiego, że 1 ∈ S k , możesz natychmiast zatrzymać: możesz znaleźć najmniejszy podzbiór, którego gcd ma wartość 1 , patrząc na podzbiór powiązany z 1 . Możesz więc zatrzymać się, gdy tylko osiągniesz zestaw S k, taki jak 1 ∈ S k , co pozwala ci zatrzymać się wcześniej, jeśli znajdziesz mniejszy podzbiór.k∈[1,2,4,8,9] 1∈Sk k 1∈Sk 1 1 Sk 1∈Sk
Powinno to być wydajne czasowo i zajmować mało miejsca. Aby zaoszczędzić miejsce, dla każdego elementu nie musisz przechowywać całego zestawu: wystarczy przechowywać dwa wskaźniki wsteczne (więc dwa elementy S i , S j , z których pobrałeś gcd, aby uzyskać x ) i opcjonalnie rozmiar odpowiedniego podzbioru.x∈Sk Si,Sj x
Zasadniczo można zastąpić sekwencję dowolnym innym łańcuchem dodawania . Nie wiem, czy jakiś inny łańcuch dodatków będzie lepszy. Optymalny wybór może zależeć od rozkładu poprawnych odpowiedzi i oczekiwanych rozmiarów zbiorów S k , co nie jest dla mnie jasne, ale prawdopodobnie można je uzyskać empirycznie poprzez eksperymenty.[1,2,4,8,9] Sk
Kredyty: Moje podziękowania dla KWillets za pomysł przechowywania podzbioru liczb wraz z każdym elementem , który pozwala wcześnie się zatrzymać.Si
źródło
Być może jest to szybsze spojrzenie na to w inny sposób ... największa liczba pierwsza mniejsza niż to 31607, dla całkowitej liczby 3401 liczb pierwszych między 2 a 31607, niezbyt duża liczba. Zapisz każdą z liczb, które otrzymałeś, w pełni ujęte w liczbach pierwszych do 31607: ai=p n i 1 1 p n i 2 2 …Pi TutajPijest liczbą pierwszą lub dużą liczbą pierwszą. Następnie zestaw zI„y jest względnie pierwsze, jeżeli odpowiednienIjwektory są liniowo niezależne (i ichPy są różne lub obu 1), a szukająstopniamacierzy.109−−−√
źródło
Jeśli jesteś w stanie znaleźć podzbiór z gcd (S) = 1, wtedy zawsze mogę usunąć zbędne elementy z podzestawu, aż pozostaną tylko 2 elementy, które mają gcd (S) = 1. Dlatego mogę twierdzić, że albo najmniejszy podzbiór będzie zawierał 2 elementy lub nie będzie istniał.
Teraz używamy rekurencji, aby rozwiązać ten problem. Podzielmy tablicę liczb na 2 części, jedną z elementami n-1 i jedną z 1 elementem (ostatni element). Albo 2 liczby będą w pierwszych n-1 elementach, albo będzie jeden element z 1. części połączonej z ostatnim elementem. Dlatego jesteśmy w stanie rozwiązać ten problem
T (n) = T (n-1) + O (n) czas. co oznacza T (n) = O (n ^ 2).
źródło