Informatyczny kącik olimpijski
Myszy
Tym razem zajmiemy się zadaniem, które pojawiło się na kolokwium dla studentów pierwszego roku informatyki na Uniwersytecie Warszawskim.
W korytarzu harcują myszy. Korytarz ma długość metrów. Dana jest tablica nieujemnych liczb całkowitych opisująca, gdzie jest ile myszy: dla na -tym metrze korytarza (patrząc od strony wejścia) jest myszy. Dysponujesz kotami Twoim zadaniem jest takie rozmieszczenie kotów w korytarzu, żeby złapały jak najwięcej myszy. Każdy kot może pilnować ustalonego przez Ciebie spójnego fragmentu korytarza (na przykład, może mieć założoną smycz odpowiedniej długości, przymocowaną do podłogi pośrodku pilnowanego fragmentu korytarza). Fragmenty korytarza pilnowane przez różne koty nie mogą zachodzić na siebie (żeby koty się nie pobiły, a smycze nie poplątały), choć mogą się stykać. Niektóre fragmenty korytarza mogą pozostać niepilnowane przez żadnego kota. Kot, który pilnuje fragmentu od -tego do -tego metra włącznie (dla ), na którym znajduje się myszy, złapie: myszy. Należy wyznaczyć maksymalną liczbę myszy, jakie mogą złapać koty (patrz rysunek).
Obojętnie, jak zabierzemy się za to zadanie, przyda się nam tablica sum prefiksowych: Wtedy liczba myszy na fragmencie przedstawia się jako
Omawiane zadanie to zadanie na programowanie dynamiczne. Niech oznacza maksymalną liczbę myszy, jakie może złapać kotów na pierwszych metrach korytarza. Ponieważ niektóre fragmenty mogą być niepilnowane, więc rekurencję budujemy, rozpatrując dwa przypadki: albo -ty metr nie jest pilnowany, albo jest i -ty kot pilnuje fragmentu (od -tego do -tego metra włącznie):
(*) |
Podstawowa implementacja zadziała w czasie Takie było oczekiwane rozwiązanie na kolokwium, niemniej jednak okazało się, że można to zrobić lepiej (ach, ci studenci). Aby przyspieszyć rozwiązanie, należy w odpowiedniej kolejności wypełniać tablicę Główna pętla powinna przebiegać po Ustalmy i załóżmy, że mamy obliczone wartości dla wszystkich Będziemy teraz obliczać element Kluczem do usprawnienia rozwiązania jest porównanie możliwych dwóch ustawień -tego kota, mianowicie gdy patroluje on fragment lub fragment gdzie Drugie ustawienie jest lepsze od pierwszego, jeśli:
Po przekształceniu nierówność przyjmie postać:
(**) |
Prawa strona nierówności zależy tylko od i (oraz od ); oznaczmy ją przez Widzimy, że pierwsze ustawienie jest lepsze dla mniejszych od po czym, począwszy od lepsze staje się drugie ustawienie. Ta obserwacja umożliwia przeglądanie możliwych ustawień -tego kota w sposób bardziej uporządkowany tak, że na bieżąco eliminujemy takie ustawienia, które są już od pewnych gorsze. Trzymamy kolejkę dwukierunkową początków fragmentów taką że
Innymi słowy, dla odpowiednio małych najlepiej przydzielać -temu kotu fragment gdy osiągnie - fragment i tak dalej aż do gdzie optymalny przydział to Przetwarzanie -tego metra korytarza składa się z następujących kroków:
- 1.
- Jeżeli kolejka ma co najmniej dwa elementy oraz to usuwamy z przodu kolejki gdyż od tego momentu lepsze będą fragmenty o początku
- 2.
- Jeżeli kolejka ma wciąż co najmniej dwa elementy, to sprawdzamy, czy Jeżeli tak, to fragmenty o początku są zdominowane przez fragmenty o początkach lub usuwamy więc z końca kolejki i powtarzamy krok 2.
- 3.
- Dodajemy na koniec kolejki.
- 4.
- Obliczamy korzystając ze wzoru ale możemy to już teraz zrobić w czasie gdyż wiemy, że maksimum jest osiągane przy gdzie jest aktualnym elementem z przodu kolejki.
W ten sposób otrzymaliśmy rozwiązanie o złożoności czasowej