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 1≤i1<⋯<ik≤n1 \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<j∧ai<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.