Forum jest zablokowane. Podczas blokady nie można dodawać ani edytować wiadomości.
Temat: Grzyby - rozwiązanie
Moje rozwiązanie w czasie O(n log^2 n):
Najpierw zauważam, że jeśli wybiorę pewien zbiór polan, to najlepiej odwiedzić je wg rosnących a_i. Więc jeśli chcę w pierwszych k dni odwiedzić pewne polany (a1,b1), ..., (ak, bk), to liczba zebranych grzybów wyniesie:
b1 + (a2 + b2) + (2a3 + b3) + ... ((k-1)ak + bk)
To samo można napisać w takiej postaci, która nie zależy od kolejności:
suma_i b_i + suma_(i<j) max(a_i, a_j)
Teraz zauważam, że przechodząc od rozwiązania dla k dni do rozwiązania dla k+1 dni, nie opłaca się wyrzucać polan. Bo jeśli powiedzmy wyrzucimy 3 polany i zastąpimy je 4 innymi, to bardziej się opłaci wziąć te wyrzucone 3 zamiast trzech dodanych o najmniejszych a_i.
Sam algorytm: będziemy dla kolejnych dni znajdować polanę, którą najbardziej się opłaca dodać do zbioru.
Dla każdej polany chcemy trzymać x_i, czyli o ile zwiększy się suma jeśli wybierzemy tę polanę.
Początkowo x_i = b_i. Po dodaniu polany (a_m,b_m), x_i zwiększa się o max(a_m, a_i).
Wszystkie niedodane polany reprezentuję jako punkty na płaszczyźnie o współrzędnych (a_i, x_i).
W każdym kroku muszę zrobić tak:
1. znaleźć najwyższy punkt (największe x_i)
2. usunąć ten punkt (a_m, x_m)
3. wszystkie punkty na lewo od niego podnieść o a_m: (a_i, x_i) -> (a_i, x_i + a_m)
4. wszystkie punkty na prawo od niego przekształcić afinicznie (a_i, x_i) -> (a_i, x_i + a_i)
W tym celu trzymam te wszystkie punkty w pełnym drzewie binarnym posortowanym po a_i. W każdym wierzchołku wewnętrznym reprezentuję górną otoczkę wypukłą punktów poddrzewa, oraz przekształcenie afiniczne tego poddrzewa.
To pozwala znajdować najwyższy punkt wyszukiwaniem binarnym w czasie O(log n), i aplikować przekształcenia afiniczne na poddrzewach.
Po usunięciu punktu i zaaplikowaniu przekształceń afinicznych po obu stronach, muszę policzyć otoczki wypukłe w O(log n) wierzchołkach wewnętrznych. Ale dwie otoczki wypukłe można połączyć znajdując odpowiedni odcinek pomiędzy nimi (most). W każdym wierzchołku wewnętrzym drzewa trzymam tylko ten most.
Most można znaleźć patrząc na wzajemne ułożenie mostów lewej i prawej otoczki. Zależnie od tego, jak one wzajemnie się układają, można wyeliminować z rozważań połowę lewej lub połowę prawej otoczki wypukłej.
Więc szukanie jednej otoczki / jednego mostu zajmuje O(log n), a cała operacja na drzewie O(log^2 n).
Najpierw zauważam, że jeśli wybiorę pewien zbiór polan, to najlepiej odwiedzić je wg rosnących a_i. Więc jeśli chcę w pierwszych k dni odwiedzić pewne polany (a1,b1), ..., (ak, bk), to liczba zebranych grzybów wyniesie:
b1 + (a2 + b2) + (2a3 + b3) + ... ((k-1)ak + bk)
To samo można napisać w takiej postaci, która nie zależy od kolejności:
suma_i b_i + suma_(i<j) max(a_i, a_j)
Teraz zauważam, że przechodząc od rozwiązania dla k dni do rozwiązania dla k+1 dni, nie opłaca się wyrzucać polan. Bo jeśli powiedzmy wyrzucimy 3 polany i zastąpimy je 4 innymi, to bardziej się opłaci wziąć te wyrzucone 3 zamiast trzech dodanych o najmniejszych a_i.
Sam algorytm: będziemy dla kolejnych dni znajdować polanę, którą najbardziej się opłaca dodać do zbioru.
Dla każdej polany chcemy trzymać x_i, czyli o ile zwiększy się suma jeśli wybierzemy tę polanę.
Początkowo x_i = b_i. Po dodaniu polany (a_m,b_m), x_i zwiększa się o max(a_m, a_i).
Wszystkie niedodane polany reprezentuję jako punkty na płaszczyźnie o współrzędnych (a_i, x_i).
W każdym kroku muszę zrobić tak:
1. znaleźć najwyższy punkt (największe x_i)
2. usunąć ten punkt (a_m, x_m)
3. wszystkie punkty na lewo od niego podnieść o a_m: (a_i, x_i) -> (a_i, x_i + a_m)
4. wszystkie punkty na prawo od niego przekształcić afinicznie (a_i, x_i) -> (a_i, x_i + a_i)
W tym celu trzymam te wszystkie punkty w pełnym drzewie binarnym posortowanym po a_i. W każdym wierzchołku wewnętrznym reprezentuję górną otoczkę wypukłą punktów poddrzewa, oraz przekształcenie afiniczne tego poddrzewa.
To pozwala znajdować najwyższy punkt wyszukiwaniem binarnym w czasie O(log n), i aplikować przekształcenia afiniczne na poddrzewach.
Po usunięciu punktu i zaaplikowaniu przekształceń afinicznych po obu stronach, muszę policzyć otoczki wypukłe w O(log n) wierzchołkach wewnętrznych. Ale dwie otoczki wypukłe można połączyć znajdując odpowiedni odcinek pomiędzy nimi (most). W każdym wierzchołku wewnętrzym drzewa trzymam tylko ten most.
Most można znaleźć patrząc na wzajemne ułożenie mostów lewej i prawej otoczki. Zależnie od tego, jak one wzajemnie się układają, można wyeliminować z rozważań połowę lewej lub połowę prawej otoczki wypukłej.
Więc szukanie jednej otoczki / jednego mostu zajmuje O(log n), a cała operacja na drzewie O(log^2 n).