CF340D Bubble Sort Graph&&Acwing896. 最長上升子序列 II
阿新 • • 發佈:2020-11-20
題意
給你一個長度為n的序列,求這個序列的最長上升子序列的長度
n<=100000
先說一下樸素的動態規劃
即設\(f[i]\)表示以\(i\)為結尾的,最長上升子序列的長度
狀態轉移
\(if(a[j]<a[i]) f[i]=max(f[i],f[j]+1)\)
可以看出,樸素的動態規劃我們的時間複雜度是\(O(n^2)\)
時間複雜度肯定過不去,那麼我們考慮怎麼優化
不難發現,一個數會產生貢獻,僅當它排在一個比它小的數後面,
我們可以開一個棧來維護
當這個新加進去的這個數比棧頂的元素小時,我們直接加進去
否則我們貪心的想,為了讓其最長,小的數用的越多越好
所以我們就二分查詢一下這個比較小的數可以放在哪裡
將比它大的那個替換掉就好
時間複雜度\(O(nlogn)\)
程式碼
#include<iostream> #include<algorithm> #include<vector> using namespace std; int main() { int n; cin >> n; vector<int>arr(n+10); for (int i = 1; i <= n; ++i)cin >> arr[i]; vector<int>stk; stk.push_back(arr[1]); for (int i = 2; i <= n; ++i) { if (arr[i] > stk.back())//如果該元素大於棧頂元素,將該元素入棧 stk.push_back(arr[i]); else//替換掉第一個大於或者等於這個數字的那個數 *lower_bound(stk.begin(), stk.end(), arr[i]) = arr[i]; } cout << stk.size() << endl; return 0; } /* 例 n: 7 arr : 3 1 2 1 8 5 6 stk : 3 1 比 3 小 stk : 1 2 比 1 大 stk : 1 2 1 比 2 小 stk : 1 2 8 比 2 大 stk : 1 2 8 5 比 8 小 stk : 1 2 5 6 比 5 大 stk : 1 2 5 6 stk 的長度就是最長遞增子序列的長度 */