Skip to content

最長増加部分列(LIS)の長さの求め方

概要

数列 \(A_n\) の増加部分列とは「すべての \(i < j\)\(A_i < A_j\) を満たす部分列」と定義される。
この増加部分列のうち、その長さが最長となるものを 最長増加部分列 (LIS: Longest Increasing Subsequence) と呼ぶ。

例えば「\(3, 1, 4, 1, 5, 9, 2, 6\)」の最長増加部分列の 1 つは「\(1, 4, 5, 6\)」で長さは 4 になる。

アルゴリズム

  1. 長さ \(n\) の増加部分列の最後の数を記録する配列 \(L_n\) を用意する。初期値はすべて∞とする。
  2. 数列 \(A_n\) を先頭から順番に見ていき、その値で \(L_n\) を更新していく。この時 \(L_n\)狭義単調増加 となるように埋めていく。また \(L_n\)できるだけ小さい値で更新 をおこなう。

Warning

これで求められるのはLISの長さのみで、具体的な最長増加部分列は求められない

計算量

アルゴリズムの手順 2 で更新位置を決める際に単純に数列の先頭から見ていく場合は \(O(N^2)\)

\(L_n\) は狭義単調増加となるように更新を行うため、2 分探索で更新位置を決めることで改善できる。このときは \(O(N\log{}N)\)

・初期状態

\(n\) 1 2 3 4 5 6 7 8
\(L_n\)

\(A_1=3\)

\(n\) 1 2 3 4 5 6 7 8
\(L_n\) 3

\(A_2=1\)
\(A_1=3>1=A_2\) なので \(L_1\) を 1 で更新する。

\(n\) 1 2 3 4 5 6 7 8
\(L_n\) 1

\(A_3=4\)

\(n\) 1 2 3 4 5 6 7 8
\(L_n\) 1 4

\(A_4=1\)
狭義単調増加となるように 1 を追加できる場所がないため更新を行わない。

・最終結果

\(n\) 1 2 3 4 5 6 7 8
\(L_n\) 1 2 5 6

\(n=4\) まで \(L_n\) が更新されているので数列 \(A_n\) の LIS は 4 となる。

参考