Masz drążków o dowolnej długości, niekoniecznie integralnych.
Cięcie niektórych patyków (jedno cięcie tnie jeden patyk, ale możemy ciąć tak często, jak chcemy), chcesz uzyskać takich, aby:
- Wszystkie te kije mają taką samą długość;
- Wszystkie kije są co najmniej tak długie, jak wszystkie inne kije.
Pamiętaj, że po wykonaniu cięć uzyskujemy drążkiC.
Jakiego algorytmu byś użył, aby liczba niezbędnych cięć była minimalna? A jaki jest ten numer?
Jako przykład weźmy i dowolne . Można zastosować następujący algorytm:n ≥ 2
- Uporządkuj drążki, malejąco według długości, aby .
- Jeśli pociąć drążek nr 1 na dwie równe części. Istnieją teraz dwa drążki o długości , które są co najmniej tak długie, jak pozostałe drążki .L 1 / 2 2 ... n
- W przeciwnym razie ( ) pociąć drążek nr 1 na dwa nierówne kawałki o rozmiarach i . Istnieją teraz dwa drążki o długości , która jest dłuższa niż a pozostałe drążki .L 2 L 1 - L 2 L 2 L 1 - L 2 3 … n
W obu przypadkach wystarczy jedno cięcie.
Próbowałem uogólnić to na większe , ale wydaje się, że jest wiele przypadków do rozważenia. Czy potrafisz znaleźć eleganckie rozwiązanie?
źródło
Zgodnie z sugestią @randomA, przejdziemy do dwóch etapów: Najpierw znajdziemy zestaw lasek, które zostaną wycięte, a następnie zminimalizujemy liczbę cięć.
Podobnie jak w przypadku szczególnym w pytaniu, sortujemy / nazywamy patyki tak, aby . Zajmuje to czas . O ( n log n )L1≥L2≥⋯≥Ln O(nlogn)
@ User1990169 jak podkreślił, nie musimy wyciąć kawałek .i≥k
W pierwszej fazie wykorzystujemy wyszukiwanie binarne w celu znalezienia liczby , , aby kije można było pociąć na co najmniej kawałków o rozmiarze (plus kilka mniejszych) , ale drążków nie można pokroić na kawałków o rozmiarze . Zajmie to czas .1 ≤ s ≤ k 1 , … , s k L s 1 , … , s - 1 k L s - 1 O ( k log k )s 1≤s≤k 1,…,s k Ls 1,…,s−1 k Ls−1 O(klogk)
Jeśli , ta wartość jest optymalnym rozmiarem i możemy pominąć fazę drugą.Ls−1=Ls
W przeciwnym razie wiemy, że optymalna wielkość spełnia a jeśli następnie wynikach cięcia co najmniej jeden z patyczków na równe wielkości kawałki. Faza druga określi :o Ls−1>o≥Ls o>Ls o o
Dla każdego kija , określ zestaw rozmiarów kandydatów w następujący sposób: Jeśli cięcie na kawałki o rozmiarze zamienia kij na kawałki (w tym krótszy, jeśli taki istnieje), kandydaci na to stick to wszystkie wartości , gdzie i . (Zobacz odpowiedź @ user1990169, aby dowiedzieć się, dlaczego są to jedyne rozmiary kandydatów).i 1≤i≤s Ls ri Lij j≤ri Lij<Ls−1
Zachowaj dla każdego rozmiaru kandydata, jak często to miało miejsce. Korzystając ze zrównoważonego drzewa wyszukiwania, można to zrobić w , ponieważ całkowita liczba kandydatów jest ograniczona przez .O(klogk) ∑iri≤2k
Teraz najczęściej wybierany rozmiar, który prowadzi do prawidłowego cięcia, to taki, który zapewnia nam optymalne rozwiązanie. Ponadto, jeśli jakikolwiek rozmiar kandydujący prowadzi do prawidłowego cięcia, każdy mniejszy rozmiar doprowadzi również do prawidłowego cięcia.
Możemy więc ponownie zastosować wyszukiwanie binarne, aby znaleźć największą długość kandydata, która prowadzi do prawidłowego cięcia w . Następnie iterujemy zestaw długości kandydatów do tego progu i znajdujemy tę o największej liczbie spośród nich w .O(klogk) O(k)
W sumie otrzymujemy środowisko wykonawcze w lub , jeśli zignorujemy (lub nie będziemy musieli) sortować początkowe.O(nlogn) O(klogk)
źródło
Po uporządkowaniu drążków w kolejności malejącej według ich długości, drążek zostanie przecięty tylko wtedy, gdy wszystkie drążki zostaną przecięte.Li L1,L2,...Li−1
Odkąd , nie będziemy robić nacięć na dalej, ponieważ zawsze możemy mieć drążków o długości .L k k L kk<n Lk k Lk
Więc teraz zamiast mamy do czynienia tylko z kijami (ewentualnie dodając ty kij jako całość), a maksymalna liczba cięć, które będą wymagane w najgorszym przypadku .k - 1 k = k - 1n k−1 k =k−1
Ponadto, jeśli optymalna liczba cięć wynosi , to wśród tych drążków musi znajdować się co najmniej jeden zestaw drążków, które należy pobrać w całości z 1 oryginalnego drążkak - 1<k−1 k−1 (w częściach lub w jednym kawałku) , tj. żadna część tego oryginalnego patyka nie może pozostać „niewykorzystana”. Wynika to z tego, że zgodnie z zasadą gołębnika należy wykonać co najmniej 1 cięcie, które będzie musiało wytworzyć więcej niż 1 ważny sztyft.
Następnie możesz przeprowadzić dwa zagnieżdżone dla pętli (oba do ). Pętla zewnętrzna oznacza numer patyka którego wszystkie części muszą zostać pobrane, a pętla wewnętrzna oznacza liczbę części wykonanych z tego patyka. Dla każdego rozmiaru sprawdź, czy możesz uzyskać wykonalne kijki, przecinając kolejno i jeśli to możliwe, zaktualizuj wymagane do tej pory minimalne cięcia, jeśli aktualna wymagana liczba jest mniejsza.i j L ik i j Lij L1
L1
Całkowita złożoność powyższego algorytmu wynosiO(nlog(n)+k3)
źródło
Ideą wysokiego poziomu byłoby wyszukiwanie binarne.
Rozmiar każdego z wymaganych drążków k będzie wynosił co najmniej najmniejszy drążek, a co najwyżej największy. Z tego powodu kontynuujemy wyszukiwanie binarne na podstawie rozmiaru środkowego drążka, zobaczmy, jaką liczbę możemy uzyskać, jeśli to jest większe niż podane to wiemy, że musimy wybrać nowy referencyjny rozmiar kandydata. Więc przechodzimy do większego lub mniejszego za pomocą nowego drążka odniesienia. Zatrzymujemy się, gdy jest mniejsze niżk ′ k k ′ kk′ k′ k k′ k
Po znalezieniu odpowiedniego drążka referencyjnego pojawia się narożny futerał, w którym należałoby jeszcze bardziej ulepszyć rozmiar. Możemy posortować wszystkie nacięte pałeczki według liczby nacięć na nich i wielkości patyka. Wybierz ten, który ma najmniejszą liczbę cięć i najmniejszy rozmiar. Zmniejsz liczbę cięć na tym drążku o 1 i zrób wszystkie drążki tego samego rozmiaru. To będzie nowy rozmiar odniesienia, sprawdź, czy ten nowy rozmiar może prowadzić do akceptowalnego . Przyznaję, że nie wiem, jak ograniczyć czas pracy w tym przypadku.k′
Mam nadzieję, że widzę coś pożytecznego z innych odpowiedzi.
źródło