Przeskocz do treści

Delta mi!

Mała Delta

Numizmatyka dla zachłannych

Tomasz Idziaszek

o artykule ...

  • Publikacja w Delcie: grudzień 2012
  • Publikacja elektroniczna: 30-11-2012
  • Wersja do druku [application/pdf]: (164 KB)

Wyobraźmy sobie następującą grę. Na stole w jednym rzędzie leży math monet o różnych nominałach. Dwoje graczy – Ania i Bartek – wykonuje na przemian ruchy, zaczyna Ania. Ruch polega na zabraniu jednej monety z lewego lub prawego końca rzędu. Wynikiem gry jest, oczywiście, suma nominałów monet zgromadzonych przez każdego z graczy. Jak powinna grać Ania, by uzyskać jak największą sumę, jeśli wie ona, że Bartek będzie grał optymalnie (tzn. będzie starał się zmaksymalizować swoją sumę)?

Na rozgrzewkę rozważmy prosty przykład dla math:

obrazek

Spróbujmy zastosować strategię zachłanną, polegającą na tym, że w każdym ruchu wybieramy ten kraniec, na którym znajduje się moneta o większym nominale. Zatem w pierwszym ruchu Ania weźmie 2:

obrazek

Optymalnym ruchem Bartka w takiej sytuacji jest wzięcie 10. Po czym Ania weźmie 5, a Bartek 1. W takiej sytuacji przewaga Ani nad Bartkiem wyniosła math (przez przewagę rozumiemy tu sumę nominałów zgromadzonych przez jednego z graczy pomniejszoną o sumę nominałów przeciwnika – nie przeszkadza nam to, że czasem ta przewaga będzie ujemna).

Okazuje się jednak, że w powyższym przykładzie Ania mogła zagrać lepiej. Wzięcie math w pierwszym ruchu powoduje, że Bartek bierze math z kolei Ania bierze math a Bartek math W takiej sytuacji przewaga Ani wynosi math

obrazek

Naiwna strategia zachłanna nie zawsze się opłaca, potrzebujemy zatem czegoś lepszego. Okazuje się, że jeśli liczba monet math jest parzysta, to Ania ma bardzo prostą strategię, dzięki której może zawsze uzyskać nieujemną przewagę, niezależnie od nominałów monet. Wyróżnijmy co drugą monetę w rzędzie:

Zauważmy, że istnieje strategia, w której Ania zabierze wszystkie wyróżnione monety. Istotnie, przed każdym ruchem Ani dokładnie na jednym krańcu będzie wyróżniona moneta (i tę monetę zabierze Ania), zaś przed każdym ruchem Bartka żadna z monet na krańcach nie będzie wyróżniona (więc Bartek nie będzie miał szans zabrać żadnej wyróżnionej monety).

Ania ma jednak wybór: może wyróżnić albo monety na pozycjach nieparzystych, albo monety na pozycjach parzystych. Oczywiście, wybierze ona ten wariant, który da jej większą sumę nominałów.

Jasne jest, że suma ta będzie równa co najmniej połowie całkowitej sumy nominałów.

Czytelnicy zechcą sprawdzić, że dla poniższego przykładu z bardziej „egzotycznymi” nominałami

obrazek

Ciąg (*)

Ciąg (*)

obrazek

Ania może uzyskać przewagę równą math zabierając monety z pozycji parzystych. Pytanie brzmi, czy ta strategia jest optymalna, tzn. czy gwarantuje Ani najlepszy możliwy wynik? Spróbujmy podejść do sprawy metodycznie. Oznaczmy wartości kolejnych nominałów w rzędzie przez math Zauważmy, że w dowolnym momencie gry na stole znajduje się spójny podciąg monet. Dla ustalenia uwagi niech będą to monety na pozycjach o numerach math (dla math). Oznaczmy przez math maksymalną możliwą do uzyskania przewagę dla gracza, który w tej sytuacji wykonuje ruch – powiedzmy, że będzie to Ania. Ma ona do wyboru dwie możliwości. Wzięcie monety z lewego krańca (o numerze math) spowoduje przejście do sytuacji, w której na stole znajdują się monety o numerach math W tej sytuacji przewaga przeciwnika (Bartka) wyniesie math zatem przewaga Ani będzie równa math Dodając zysk math z math -tej monety, widzimy, że po tym ruchu przewaga Ani wyniesie math Rozumując analogicznie, otrzymujemy, że wzięcie monety z prawego krańca (o numerze math) daje jej przewagę math Zatem wartości tablicy math można wyznaczyć za pomocą następującej rekurencji:

display-math

obrazek

Na marginesie znajduje się tablica dla naszego ciągu (*). Przykładowo, aby wyznaczyć wyróżniony element tablicy, obliczamy

display-math

Tak więc przewaga Ani w naszym przykładzie wynosi math Można ją uzyskać, biorąc w pierwszym ruchu monetę o nominale math a dalej grając zachłannie.

Tabelka koduje optymalną strategię dla całej gry. Problematyczne jest jednak to, że do jej wyznaczenia potrzebujemy wykonać math obliczeń, nawet jeśli chcemy wyznaczyć tylko pierwszy ruch Ani lub jej przewagę w grze. Podamy teraz prostszy sposób na wyznaczanie tych rzeczy.

Znajdźmy w ciągu trzy monety na kolejnych pozycjach math których nominały spełniają nierówności math i zastąpmy je jedną monetą o nominale math Jeśli istnieje więcej takich trójek, to wybieramy dowolną z nich. Okazuje się (choć nie jest to ani oczywiste, ani łatwe do uzasadnienia), że taka operacja nie zmienia przewagi Ani. Stosując ją w naszym przykładzie (*), dostajemy:

obrazek

Jeśli ciąg nominałów jest bitoniczny (tzn. do pewnego momentu malejący, a dalej rosnący – czyli nie uda się znaleźć trzech monet spełniających powyższy warunek), to w takim przypadku działa już strategia zachłanna. Jest tak dlatego, że niezależnie od kolejnych ruchów największa moneta będzie zawsze znajdowała się na jednym z krańców ciągu. Zatem przewagę Ani w przypadku ciągu bitonicznego bardzo łatwo obliczyć – wystarczy zsumować liczby w porządku nierosnącym, biorąc co drugą liczbę ze znakiem minus. W naszym przypadku będzie to math

Czytelnicy zechcą sprawdzić, że w przykładzie

obrazek

po zastosowaniu trzech operacji uzyskujemy bitoniczny ciąg

obrazek

zatem i tym razem przewaga wynosi math

A co z wyznaczeniem optymalnego ruchu? Otóż, jeśli w bitonicznym ciągu, powstałym po serii operacji, lewy nominał wynosi co najmniej tyle ile prawy (a zatem wzięcie monety z lewego krańca jest optymalnym ruchem), to również w pierwotnym ciągu wzięcie monety z lewego krańca jest optymalnym ruchem. Analogicznie w przypadku prawego krańca. Zatem w ciągu (**) wzięcie math z lewego krańca jest optymalne, gdyż w ciągu bitonicznym nominał na lewym krańcu jest większy niż ten na prawym math.

Ostatecznie otrzymujemy przepis, który pozwala nam wyznaczyć optymalny ruch i wymaga jedynie liczby obliczeń rzędu math