https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_x
概要 : 配列 $A$ を与える。最長部分増加列の長さを求めろ。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<int>a(n);
for(int i=0;i<n;++i)cin>>a[i];
const int inf = 1<<30;
vector<int> LIS(n,inf);
LIS[0]=a[0];
for(int i=1;i<n;++i){
const int &target = a[i];
auto it = lower_bound(LIS.begin(),LIS.end(),target);
*it = a[i];
}
int ans = lower_bound(LIS.begin(),LIS.end(),inf) - LIS.begin();
cout << ans << endl;
}
DPテーブルに増加部分列の長さをindexとしたときの最後の$A_i$の値を入れていく。
$\mathrm{DP}[0]$ は 自明に $A_0$ になる。
そこから $A_i$ を見ていき $\mathrm{DP}[0]$ から $\mathrm{DP}[n-1]$ までの値の中で $A_i$ より大きい値を見つけたらそのDPテーブルのindexに $A_i$ を入れる。
以上を繰り返す。
DPテーブルに inf 以外の値が入っている個数は最長部分増加列の長さになる。
<aside> 🚫
DPテーブルの値が最長部分増加列自体ではないことに注意
</aside>