RE:ゼロから始めるLIS問題
最長部分増加列(LIS)問題は序列の単調増加の部分列の中で一番長い部分列の長さを求める問題である。最近ARC 104の問題
を見ていたらLIS問題を振り替えようと思います。
貪欲アルゴリズム
配列]があるとする。dp[i]は長さがiの部分増加列の最後の要素の最小値を表す。例えば列全体に対して、長さが4になる部分増加列はなどの五通りある。その中で最後の要素の最小値は4なのでdp[4]=4になる。
このアルゴリズムは配列の要素ごとに以下のプロセスを繰り返す。
- 配列の要素をみる
- 今の最長増加列の長さをmとすると、二分探索でより大きい要素をdpから探す。
- 見つかったらその要素をと置き換える。
- 見つからなかった場合は長さを1増やして、dp配列の最後をと置く。
このアルゴリズムは簡単で、ツリー上のLIS問題にも適用する。
BITを用いたdpアルゴリズム
また配列dpを用意して、今回はを「iが最後となる部分増加列の長さ」にする。BITを使って効率よくからまでの最大値を探す。アルゴリズムは元の配列要素ごとに以下のプロセスを繰り返す。
- 配列の要素をみる
- からまでの最大値tmpを探す
- をにする
この方法が成立する前提は全ての要素更新は要素を大きくすること。そして区間最大値は全部初めから計算したもの。この方法は貪欲アルゴリズムより複雑だけど、LISだけでなくより複雑な制約を扱える。例えばこのLaIS問題。