Mój 8-latek znudził się tworzeniem konwencjonalnych labiryntów i zaczął tworzyć warianty, które wyglądają tak:
Chodzi o to, aby zacząć od x i osiągnąć normalne zasady. Dodatkowo możesz „przeskoczyć” z dowolnej liczby całkowitej na inną liczbę całkowitą , ale musisz zapłacić dolarów za przywilej. Celem jest rozwiązanie labiryntu przy jak najniższych kosztach. W powyższym przykładzie możemy przejść od x do o przez x-14-18-27-28-o po koszcie 5, ale taniej jest przejść x-13-11-9-8-29-28-o tylko 4
Oto moje pytanie: jakie jest najlepsze rozwiązanie (jeśli chodzi o asymptotyczny czas działania), które możesz wymyślić w celu rozwiązania tego problemu? Możesz przyjąć wszelkie uzasadnione założenia dotyczące formatu wejściowego.
Uwaga: używam tutaj tagu „puzzle”, ponieważ mam na myśli odpowiedź , ale nie jestem pewien, czy jest optymalna i chciałbym sprawdzić, czy ktoś inny może poprawić moje rozwiązanie. (Tutaj to liczba całkowita w labiryncie.)
Odpowiedzi:
Możesz to rozwiązać w czasie przy użyciu odmiany algorytmu Dijkstry. Nie możemy wykonać wszystkich aktualizacji odległości, gdy odwiedzimy nowy węzeł. Jeśli odwiedzimy węzeł y , musimy jedynie zaktualizować odległości od wszystkiego, na co można przejśćO(nlogn) y do 0, i zaktualizować odległości do dwóch węzłów y - i y + z najbliższymi wartościami y mniejszymi i większymi niż y, które nie został jeszcze wybrany.y y− y+ y y
Te aktualizacje są wystarczające, aby sterty zwracały minimalny element, ponieważ najbliższy węzeł, do którego przeskakujesz, musi znajdować się liczbowo tuż nad lub tuż pod wcześniej odwiedzonym węzłem.
Każdy węzeł jest aktualizowany co najwyżej do 0 (jeśli usuniemy wszystkie węzły o zerowej odległości z kolejki, aby uniknąć zachowania kwadratowego), i za każdym razem, gdy dodamy węzeł, wykonujemy tylko inne aktualizacje O (1). Znalezienie wartości i y + można wykonać w czasie liniowym, jeśli będziemy również przechowywać uporządkowaną podwójnie połączoną listę wszystkich węzłów, posortowaną według ich wartości całkowitych. Zbudowanie tej podwójnie połączonej listy zajmuje O ( n log n ) , a na koniecy− y+ O(nlogn) aktualizacje O ( n ) i wyskakujące ze stosu zajmują czas O ( n log n ) , co daje całkowity czas działania O (O(n) O(nlogn) O(nlogn)
źródło
Czuję, że może być najlepszym, co możesz dostać.O(n2)
Naturalne wydaje się przekształcenie tego problemu w najkrótszą ścieżkę za pomocą specjalnego węzła początkowego (x) i węzła końcowego (0). Byłby również jeden inny węzeł dla każdej liczby. Zarówno x, jak i 0 mają krawędzie o wadze 0 do wszystkich węzłów liczbowych, które są osiągalne w labiryncie. Wszystkie węzły liczbowe są połączone albo z wagą 0 (jeśli liczby są osiągalne w labiryncie), albo z różnicą między liczbami (jeśli nie można osiągnąć labiryntu).
Najkrótszej ścieżki na tym wykresie nie można rozwiązać w zakresie mniejszym niż ponieważ wykres ma z grubsza n 2 krawędzi, aw najgorszym przypadku każdy przypadek musiałby zostać wyświetlony raz. Jako taki, algorytm Dijkstra'a dla najkrótszej ścieżki zajmuje czas O ( n 2 ) i jest optymalny w najgorszym przypadku.O(n2) n2 O(n2)
źródło