Omówienie zadania Rycerz (II etap XXXI OI)

Ogólne podejście

Będziemy rozpatrywać kolejne miecze od pierwszego i obliczać dla nich największą możliwą do uzyskania wartość przy założeniu, że chcemy uzyskać też (już obliczone) wartości mieczy o mniejszych numerach.

Podproblem

Zanim zajmiemy się obliczaniem tych maksymalnych wartości, zastanówmy się nad następującym podproblemem. Powiedzmy, że mamy dany ciąg w1,,wk i naszym zadaniem jest tylko stwierdzić, czy jesteśmy w stanie uzyskać zestaw mieczy taki, żeby wartość i-tego miecza była równa przynajmniej wi.

Zdefiniujmy nowy graf, w którym wierzchołek oznacza parę (miasto, podzbiór mieczy), przy czym podzbiór mieczy oznacza miecze, dla których osiągnęliśmy już zamierzony cel. Dla każdej krawędzi sprawdzamy, jaki podzbiór mieczy osiąga cel, i tworzymy przejście między wierzchołkami: (v,s)(u,sz) dla krawędzi z v do u oraz wyliczonym dla niej podzbiorem z. Na tym nowym grafie możemy wykorzystać algorytm BFS z wierzchołka 1 aby sprawdzić, czy jesteśmy w stanie dotrzeć do wierzchołka n z pełnym zbiorem mieczy po co najwyżej d krokach. Ten podproblem rozwiązaliśmy w czasie O(2k(n+m)).

Wyszukiwanie binarne

Powiedzmy, że chcemy obliczyć wynik dla i-tego miecza i znamy już wartości w1,,wi1. Możemy wyszukiwać binarnie szukaną wartość wi: możemy sprawdzić, czy zachodzi wix, poprzez rozwiązanie podproblemu dla w1,,wi1,x. Ważnym jest, aby rozwiązywać ten podproblem przy założeniu, że jest tylko i mieczy (zamiast k), ponieważ pozostałe nie wpływają na szukaną wartość wi. Wtedy uzyskamy złożoność O((21+22++2k)(n+m)logm)=O(2k(n+m)logm).

Rozwiązanie wzorcowe

Korzystając ze wspomnianego podproblemu, trudno jest uzyskać rozwiązanie lepsze niż to z wyszukiwaniem binarnym. Chcemy, aby rozwiązanie podproblemu dawało nam więcej informacji. Załóżmy, że mamy obliczone już wartości w1,,wi1. Chcielibyśmy teraz dla każdej krawędzi stwierdzić, czy jesteśmy w stanie przejść daną krawędzią na jakiejś ścieżce długości co najwyżej d z 1 do n, uzyskując wartości w1,,wi1 na mieczach 1,,i1. W tym celu obliczymy za pomocą BFS odległości z wierzchołka 1 oraz odległości z wierzchołka n. Nazwijmy je pv,s oraz qv,s, gdzie v to numer miasta, a s to podzbiór mieczy. Następnie dla krawędzi z u do v sprawdzamy, czy pu,s+qv,z+1d, gdzie sz jest pełnym zbiorem i1 mieczy. Aby nie przeglądać każdej pary s oraz z wystarczy sprawić, aby tablica qv,s oznaczała minimalną liczbę kroków potrzebną do uzyskania co najmniej zbioru mieczy s w mieście v. Po takiej poprawce wystarczy dla pojedynczej krawędzi przeiterować się po każdym zbiorze s i przyjąć za z dopełnienie s do zbioru wszystkich mieczy. To rozwiązanie działa w analogiczny sposób w złożoności O(2k(n+m)).