Najdłuższy podciąg rosnący

by Jerry Sky

2020-04-08



Input

Ciąg A=(a1,,an)A = (a_1,\dots,a_n)

Output

Najdłuższy rosnący podciąg AA.

Podciągiem ciągu AA nazywamy ciąg (ai1,,aik)(a_{i_1}, \dots, a_{i_k}), gdzie 1i1<<ikn1 \le i_1 < \dotsb < i_k \le n, jeśli dodatkowo ma on być rosnący to ai1<<aika_{i_1} < \dotsb < a_{i_k}.

Przykład AA

Mamy A=(5,2,8,5,3,7,9,8)A = (5,2,8,5,3,7,9,8).

Wówczas najdłuższy pociąg AA to np. (2,3,7,9)(2,3,7,9), ale istnieją również inne podciągi tej samej długości np. (2,5,7,8)(2,5,7,8).

Steps

  1. Budujemy DAG G=(V,E,c)G = (V,E,c) odpowiadającego naszemu problemowi.
  2. Niech zbiór wierzchołków stanowią elementy ciągu wejściowego AA: V={a1,,an}V = \{a_1,\dots,a_n\}.
  3. Wstawiamy krawędzie tylko pomiędzy wierzchołkami, które mogą być kolejnymi elementami rosnącego podciągu, czyli (ai,aj)E(a_i, a_j) \in E jeśli i<jai<aji<j \land a_i < a_j.
  4. Niech waga (długość) każdej krawędzi będzie równa 11, czyli (u,v)E:c(u,v)=1\forall(u,v) \in E: c(u,v) = 1.

Zauważmy, że tak powstały graf GG jest DAG-iem oraz, że ścieżki w tak zdefiniowanym grafie odpowiadają podciągom rosnącym ciągu AA. Zatem naszym zadaniem teraz jest znalezienie najdłuższej ścieżki w tak zdefiniowanym grafie.

Znalezienie najdłuższej ścieżki

Niech L(i)L(i) będzie długością najdłuższego podciągu kończącego się na elemencie aia_i, wówczas:

for i = 1 to n:
  L(i) = 1 + max{ L(j): (j,i) in E }
return max{ L(i): i in [n] }

Podobnie jak w problemie najkrótszej ścieżki w DAG, jeśli zapamiętamy aja_j dla którego osiągnięty jest max{L(j):(j,i)E}\max\{L(j): (j,i) \in E\} to możemy odtworzyć uzyskany w wyniku podciąg.

Złożoność obliczeniowa powyższego algorytmu wynosi O(E)O(|E|) (podobnie jak to było w przypadku najkrótszych ścieżek w DAG), czyli w pesymistycznym przypadku O(n2)O(n^2), który zachodzi jeśli ciąg wejściowy jest posortowany rosnąco.