Informatyczny kącik olimpijski
Wieża z siana
W tym miesiącu zadanie Tower of Hay, które pojawiło się na konkursie USACO Open Gold w roku 2009.

Rys. 1 Dla beli o kolejnych szerokościach 7, 6, 4, 2, 1, 4 można zbudować wieżę o wysokości 4
Zadanie. Z prostopadłościennych beli siana, które mają tę samą wysokość, ale różne szerokości
chcemy zbudować wielopoziomową wieżę. Na każdy poziom może się składać kilka beli, a sumaryczna szerokość każdego poziomu musi być nie większa niż sumaryczna szerokość poziomu znajdującego się bezpośrednio pod nim (o ile taki istnieje). Co więcej, żadna bela nie może znajdować się na wyższym poziomie niż inna bela o wyższym numerze (czyli należy je układać po kolei) i należy wykorzystać wszystkie bele. Jaka jest największa możliwa wysokość wieży, którą można zbudować przy takich założeniach (patrz Rys. 1)?

Rys. 2 Algorytm zachłanny dla beli z rysunku 1 zbuduje wieżę o wysokości 3
Dość naturalnym rozwiązaniem zachłannym, które może się nam narzucić, jest konstruowanie każdego poziomu z jak najmniejszej liczby beli siana, podczas budowania wieży od góry. Niestety, jest to rozwiązanie niepoprawne, jak można się przekonać, patrząc na rysunek 2.
Spróbujmy więc rozwiązania opartego o metodę programowania dynamicznego. Niech oznacza maksymalną wysokość wieży złożonej z beli o szerokościach
jeśli dolny poziom wieży składa się z beli o szerokościach
Wtedy mamy następującą rekurencję, w której iterujemy po wszystkich możliwościach zbudowania drugiego poziomu (przyjmujemy tu oznaczenie
):
![]() |
Czas wypełniania tablicy to
a odpowiedź to
Można nieco zmodyfikować powyższy pomysł, aby uzyskać rozwiązanie o złożoności czasowej Oznaczmy przez
maksymalną wysokość wieży złożonej z beli
w której dolny poziom nie zawiera beli
Rekurencja przybierze postać
![]() |
gdzie jest maksymalnym indeksem, dla którego
Taki indeks możemy obliczać na bieżąco, jeśli ustalimy indeks
i będziemy wypełniać tablicę
kolejno dla rosnących wartości indeksu
Odpowiedź to

Jeszcze lepsze rozwiązanie uzyskamy, korzystając z obserwacji, że najwyższa wieża będzie miała też najmniejszą szerokość dolnego poziomu. Udowodnijmy to przez indukcję: pokażemy to dla wieży zbudowanej z beli przy założeniu, że teza jest spełniona dla wież zbudowanych z beli o szerokościach
dla
Załóżmy, że wieża o najmniejszej szerokości dolnego poziomu ma go zbudowanego z beli
Wtedy najwęższa wieża z beli
będzie miała (na mocy założenia indukcyjnego) największą wysokość
(a zatem cała wieża wysokość
). Teraz dowolna inna wieża mająca dolny poziom
dla
ma resztę zbudowaną z
o wysokości
(zatem cała wieża ma wysokość
). Ale wtedy istnieje wieża złożona z
o wysokości
(bo wystarczy rozszerzyć dolny poziom), zatem
(z maksymalności
). To kończy dowód.
Niech zatem oznacza taki indeks
że najwęższa wieża zbudowana z beli o szerokościach
ma dolny poziom złożony z beli o szerokościach
Wtedy mamy rekurencję:
![]() |
Wyznaczywszy tablicę w czasie
odpowiedź odzyskujemy, obliczając długość ciągu
zawierającego końce kolejnych poziomów w najwęższej wieży.
Tablicę można wypełnić szybciej. Ustalmy indeks
i niech
będzie maksymalnym indeksem, dla którego spełniona jest nierówność
Wiemy zatem, że
dla wszystkich
Algorytm jest następujący: dla kolejnych indeksów
wykonujemy przypisanie
wyznaczamy wyszukiwaniem binarnym indeks
i wykonujemy
Złożoność czasowa tego algorytmu to
A Czytelników Dociekliwych zachęcamy do rozwiązania tego zadania w optymalnej złożoności czasowej