The Hitchhiker's Guide to the Programming Contests に記載されているアルゴリズムを見つけました(注: この実装では、リストに重複がないことを前提としています):
set<int> st;
set<int>::iterator it;
st.clear();
for(i=0; i<n; i++) {
st.insert(array[i]); it=st.find(array[i]);
it++; if(it!=st.end()) st.erase(it);
}
cout<<st.size()<<endl;
O(NlogN) で最も長く増加する部分列を見つけるアルゴリズムです。いくつかのテストケースで動作させようとすると、動作するようです。しかし、私はまだその正当性ロジックを理解できませんでした。また、私にはそれほど直感的に見えません。
このアルゴリズムが正しく機能する理由について洞察を得るのを手伝ってくれる人はいますか?