Ciąg binarny to ciąg, który zawiera tylko znaki zaczerpnięte z 01 . Wynosi ciąg binarny jest binarny ciąg, który zawiera dokładnie jak najwięcej 0 s jako 1 s.
Otrzymujesz dodatnią liczbę całkowitą n i dowolną liczbę masek, z których każda ma długość 2n znaków i zawiera tylko znaki wyciągnięte z 012 . Łańcuch binarny i maska pasują, jeśli ma taką samą długość i zgadza się na znak w każdej pozycji, w której maska nie ma 2 . Np maska 011022 mecze binarne ciągi 011000 , 011001 , 011010 , 011011 .
Biorąc pod uwagę n i maski jako dane wejściowe (oddzielone znakami nowej linii), musisz wyprowadzić liczbę różnych zrównoważonych ciągów binarnych pasujących do jednej lub więcej masek.
Przykłady
Wejście
3
111222
000112
122020
122210
102120
Rozumowanie
- Jedyny zrównoważony ciąg binarny pasujący do 111222 to 111000 .
- Jedyny zrównoważony ciąg binarny pasujący do 000112 to 000111 .
- Zrównoważone ciągi binarne pasujące do 122020 to 111000 (już policzone), 110010 i 101010 .
- Zrównoważone ciągi binarne pasujące do 122210 to 110010 (już policzone), 101010 (już policzone) i 100110 .
- Zrównoważone ciągi binarne pasujące do 102120 to 101100 i 100110 (już policzone).
Tak więc wynik powinien być
6
Wejście
10
22222222222222222222
Rozumowanie
- Jest 20 do wyboru 10 zbalansowanych ciągów binarnych o długości 20.
Wynik
184756
Zwycięzca
Zwycięzcą zostanie ten, który najszybciej obliczy wkład konkurencji, oczywiście traktując go tak samo, jak każdy inny wkład. (Używam określonego kodu, aby mieć wyraźnego zwycięzcę i unikać przypadków, w których różne dane wejściowe dawałyby innym zwycięzcom. Jeśli zastanawiasz się, jak znaleźć najszybszy kod, powiedz mi to).
Wkład konkurencji
źródło
Odpowiedzi:
do
Jeśli nie korzystasz z systemu Linux lub masz problemy z kompilacją, prawdopodobnie powinieneś usunąć kod czasowy (
clock_gettime
).Przykładowe przypadki:
(Czasy dotyczą procesora i7-4770K przy 4,1 GHz.) Bądź ostrożny,
testcase-hard
zużywa około 3-4 GB pamięci.Jest to w zasadzie implementacja metody blokowania wykluczeń, która została wymyślona, ale zrobiona tak, aby obsługiwała skrzyżowania o dowolnej głębokości.
Napisany kod spędza dużo czasu na alokacji pamięci i będzie jeszcze szybszy, gdy zoptymalizuję zarządzanie pamięcią.Ogoliłem około 25%
testcase-hard
, ale wydajność oryginalnego (testcase-long
) jest prawie niezmieniona, ponieważ tam nie dzieje się tak dużo alokacji pamięci. Zanim zadzwonię, dostroję trochę więcej: myślę, że mogę uzyskać 25% -50% poprawętestcase-long
.Matematyka
Gdy zauważyłem, że to problem #SAT, zdałem sobie sprawę, że mogę użyć wbudowanego Mathematica
SatisfiabilityCount
:Wynik:
To 298 208 861 472 masek w 1,3 sekundy (i7-3517U @ 1,9 GHz), w tym czas poświęcony na pobranie testowej skrzynki z pastebin.
źródło
testcase-hard
można wykonać bardzo szybko, jeśli kod szuka masek, które można łączyć. Jeśli twój kod to robi, usuń co drugi wiersz (więc pozostały tylko/^2*02*$/
przypadki). Nie sądzę, że ten przypadek można zoptymalizować.rubinowy, dość szybki, ale zależy to od danych wejściowych
Teraz przyspieszenie o współczynnik 2 ~ 2,5 poprzez zmianę ciągów znaków na liczby całkowite.
Stosowanie:
Na przykład.
Liczba dopasowań dla pojedynczej maski jest łatwo obliczana przez współczynnik dwumianowy. Na przykład
122020
wymaga 32
s wypełnienia, 10
i 21
. Zatem istniejąnCr(3,2)=nCr(3,1)=3!/(2!*1!)=3
różne ciągi binarne pasujące do tej maski.Przecięcie n maski m_1, m_2, ... m_n jest maską q, tak że ciąg binarny s pasuje do q tylko iff pasuje do wszystkich m_i.
Jeśli weźmiemy dwie maski m_1 i m_2, jego przecięcie można łatwo obliczyć. Wystarczy ustawić m_1 [i] = m_2 [i], jeśli m_1 [i] == 2. Przecięcie między
122020
i111222
jest111020
:Dwie indywidualne maski są dopasowane przez 3 + 1 = 4 ciągi, maska przecięcia jest dopasowana przez jeden ciąg, więc istnieją 3 + 1-1 = 3 unikalne ciągi pasujące do jednej lub obu masek.
Wywołam N (m_1, m_2, ...) liczbę ciągów pasujących do wszystkich m_i. Stosując tę samą logikę jak powyżej, możemy obliczyć liczbę unikatowych ciągów dopasowanych przez co najmniej jedną maskę, podaną przez zasadę wykluczania włączenia, i patrz również poniżej:
Istnieje wiele, wiele kombinacji kombinacji, powiedzmy 30 masek na 200.
To rozwiązanie zakłada więc, że nie ma wielu przecięć wyższych rzędów masek wejściowych, tj. większość n-krotek n> 2 masek nie będzie mieć wspólnych dopasowań.
Użyj kodu tutaj, kod w ideone może być przestarzały.
Dodałem funkcję,
remove_duplicates
której można użyć do wstępnego przetworzenia danych wejściowych i usuwania masek,m_i
tak aby wszystkie pasujące do nich ciągi pasowały również do innej maskim_j
., W przypadku bieżącego wprowadzania danych trwa to dłużej, ponieważ nie ma takich masek (lub ich niewiele) , więc funkcja nie jest jeszcze stosowana do danych w poniższym kodzie.Kod:
Nazywa się to zasadą wykluczenia włączenia, ale zanim ktoś mi to wskazał, miałem swój własny dowód, więc proszę bardzo. Robienie czegoś samemu sprawia jednak przyjemność.
Rozważmy przypadek 2 masek, zadzwoń wtedy
0
i1
najpierw. Bierzemy każdy zbalansowany ciąg binarny i klasyfikujemy go według pasujących masek.c0
to liczba pasujących tylko do maski0
,c1
liczba pasujących tylko pasujących1
,c01
pasujących do maski0
i1
.Niech
s0
będzie sumą liczbową liczby dopasowań dla każdej maski (mogą się nakładać). Niechs1
będzie sumą liczby dopasowań dla każdej pary (2 kombinacji) masek. Niechs_i
będzie sumą liczby dopasowań dla każdej (i + 1) kombinacji masek. Liczba dopasowań n-masek to liczba ciągów binarnych pasujących do wszystkich masek.Jeśli jest n masek, pożądanym wynikiem jest suma wszystkich
c
, tj.c = c0+...+cn+c01+c02+...+c(n-2)(n-1)+c012+...+c(n-3)(n-2)(n-1)+...+c0123...(n-2)(n-1)
. Program oblicza na przemian sumę wszystkichs
, tzn.s = s_0-s_1+s_2-+...+-s_(n-1)
. Chcemy to udowodnićs==c
.n = 1 jest oczywiste. Zastanów się n = 2. Zliczanie wszystkich dopasowań maski
0
dajec0+c01
(liczba ciągów pasujących tylko do 0 + pasujących do obu0
i1
), liczenie wszystkich dopasowań1
dajec1+c02
. Możemy to zilustrować w następujący sposób:Z definicji
s0 = c0 + c1 + c12
.s1
to łączna liczba dopasowań każdej 2 kombinacji[0,1]
, tj. wszystkie uniqyec_ij
s. Pamiętaj o tymc01=c10
.Zatem
s=c
dla n = 2.Teraz rozważ n = 3.
Zatem
s=c
dla n = 3.c__i
reprezentuje wszystkiec
s ze wskaźnikami (i + 1), np.c__1 = c01
dla n = 2 ic__1 = c01 + c02 + c12
dla n == 3.Dla n = 4 zaczyna się pojawiać wzór:
Zatem
s==c
dla n = 4.Ogólnie rzecz biorąc, otrzymujemy współczynniki dwumianowe takie jak to (↓ to i, → to j):
Aby to zobaczyć, uważają, że dla niektórych
i
ij
istnieją:Może się to wydawać mylące, oto definicja zastosowana do przykładu. Dla i = 1, j = 2, n = 4 wygląda to tak (patrz wyżej):
Więc tutaj x = 6 (01, 02, 03, 12, 13, 23), y = 2 (dwa c z trzema indeksami dla każdej kombinacji), z = 4 (c012, c013, c023, c123).
W sumie istnieją
x*y
współczynnikic
o indeksach (j + 1) i są onez
różne, więc każdy zachodzix*y/z
razy, które nazywamy współczynnikiemk_ij
. Prostą algebrą otrzymujemyk_ij = ncr(n,i+1) ncr(n-i-1,j-i) / ncr(n,j+1) = ncr(j+1,i+1)
.Tak więc indeks podaje:
k_ij = nCr(j+1,i+1)
Jeśli przypomnisz sobie wszystkie definicje, wszystko, co musimy wykazać, to że naprzemienna suma każdej kolumny daje 1.Suma naprzemienna
s0 - s1 + s2 - s3 +- ... +- s(n-1)
może zatem być wyrażona jako:Zatem
s=c
dla wszystkich n = 1,2,3 ...źródło
0011 < 2211
,0022 < 0222
. Myślę, że to czyni grupy nie większymi niż2*n
, choć w najgorszym przypadku wciąż jest zbyt duża.unifying two masks
ten terminunion
ma sens i ja Xan tak to określam, ale masz rację, w interesie wzajemnego zrozumienia, o którym mówiłem. @ Agawa001 Czy możesz być bardziej szczegółowy? Ponadto, jeśli masz jakiś dobry pomysł, aby przyspieszyć, skorzystaj z pomysłów z tej odpowiedzi dla swojego programu / odpowiedzi. Na razie jest wystarczająco szybki dla dużego przypadku testowego, a jeśli zostanie wykonany wielowątkowo, powinien zająć <0,1 s, co jest poniżej jakiegokolwiek znaczącego pomiaru / porównania, więc potrzebne są trudniejsze przypadki testowe.do
Powodzenia w uzyskaniu dużego wkładu w to - prawdopodobnie zajmie całą noc, aby przejść ok. 60 ^ 30 permutacji! Może zestaw danych o średniej wielkości może być dobrym pomysłem?
źródło