Kieszonkowe
Dzisiejsze zadanie pochodzi z VIII. Olimpiady Informatycznej Gimnazjalistów w roku szkolnym 2013/2014.
Zadanie. Danych jest stosów, ponumerowanych od do Każdy stos zawiera dokładnie dwie monety, ułożone jedna na drugiej. Ciąg oznacza nominały monet, znajdujących się na górze kolejnych stosów, zaś ciąg nominały monet, znajdujących się na dole kolejnych stosów. Staś, bohater zadania, może wykonać co najwyżej ruchów. W każdym ruchu chłopiec wybiera dowolny niepusty stos i zabiera monetę ze szczytu tego stosu. Jaki jest największy możliwy zysk Stasia?
Rozwiązanie dynamiczne. Zadanie możemy rozwiązać, korzystając z metody programowania dynamicznego. Niech oznacza maksymalny zysk dla problemu ograniczonego do stosów o numerach od do oraz maksymalnej liczbie ruchów równej Łatwo obliczyć wartości dla pierwszego stosu :
- ;
- ;
- dla
Przejdźmy teraz do obliczenia wyników dla większej liczby stosów. Dla każdego oraz aby obliczyć wartość należy rozpatrzyć trzy sytuacje:
- nie bierzemy ani jednej monety z -tego stosu, wtedy wynikiem jest ;
- bierzemy jedną monetę z -tego stosu, wtedy wynikiem jest ;
- bierzemy dwie monety z -tego stosu, wtedy wynikiem jest
Wartością jest maksimum z trzech powyższych wartości. Oczywiście, druga sytuacja jest możliwa tylko dla podobnie trzecia tylko dla Największym zyskiem Stasia jest
Wszystkich stanów jest Obliczenie wyniku dla każdego stanu odbywa się w czasie stałym. Stąd złożoność czasowa rozwiązania wynosi
Rozwiązanie zachłanne. Okazuje się, że istnieje rozwiązanie o lepszej złożoności czasowej. Na początku podzielmy stosy na dwie grupy. Niech pierwsza grupa zawiera stosy, których górna moneta ma nominał nie mniejszy niż dolna moneta, nazwijmy je -stosami. Pozostałe stosy niech tworzą drugą grupę i nazwijmy je -stosami. Każdą z tych grup rozważmy oddzielnie.
Przypadek 1: Załóżmy, że mamy -stosów. Chcemy wybrać monet, których sumaryczna wartość jest największa. Załóżmy dodatkowo, że w każdym ruchu możemy wybrać dowolną monetę (górną lub dolną). Nietrudno zauważyć, że aby zmaksymalizować zysk, należy wybrać monet o największym nominale. Zatem posortujmy wszystkie monety malejąco według nominału. Otrzymujemy ciąg oznaczający wartości wszystkich monet. Największy zysk uzyskamy, jeśli weźmiemy następujące monety:
Strategia zachłanna, która została opisana powyżej, jest również poprawna bez dodatkowego założenia o braniu dowolnej monety. Ustalamy zatem, że możemy brać tylko monety ze szczytu stosu. Przypuśćmy, że w optymalnym rozwiązaniu chcemy wziąć dwie monety (górną) i (dolną), które tworzą jeden stos. Skoro rozważamy -stos oraz ciąg jest posortowany malejąco, to Zatem strategia zachłanna jest poprawna, ponieważ najpierw wybierze górną monetę a dopiero potem dolną Tutaj jest drobna subtelność, jeśli dwie monety mają ten sam nominał, wtedy pierwszeństwo ma górna.
Przypadek 2: Załóżmy, że mamy -stosów. Chcemy wybrać monet, których sumaryczna wartość jest największa. Przypuśćmy, że w optymalnym rozwiązaniu istnieją dwa stosy (o numerach oraz ), z których zabieramy po jednej monecie. Bez straty ogólności możemy założyć, że Wiadomo (z własności -stosu), że Skoro oraz to Zatem wzięcie po jednej monecie ze stosów i nie jest optymalnym rozwiązaniem, gdyż bardziej opłaca się wziąć dwie monety z -tego stosu. Stąd otrzymujemy, że w optymalnym rozwiązaniu nie ma dwóch stosów, z których zabieramy po jednej monecie. Innymi słowy, jest co najwyżej jeden stos, z którego zabieramy jedną monetę.
Zatem posortujmy stosy według malejącej sumy nominałów. Otrzymujemy ciąg gdzie oznacza sumę nominałów -tego najcenniejszego stosu. Jeśli jest parzyste, to wybieramy monety ze stosów W przeciwnym przypadku rozważamy dwie sytuacje. Pierwsza z nich polega na wzięciu stosów oraz monety o największym nominale spośród szczytów pozostałych stosów. Druga zaś polega na wzięciu stosów bez monety o najmniejszym nominale spośród spodów wybranych stosów.
Podsumowanie. Rozwiązanie opiera się na rozpatrzeniu dla każdego następującego przypadku: wybieramy monet z -stosów oraz monet z -stosów. Wynikiem jest maksimum spośród wyników dla tych przypadków. Całe rozwiązanie działa w czasie Szczegóły implementacyjne pozostawiam Czytelnikowi jako ćwiczenie.