时间复杂度n * log n
加个二分
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 100010; 4 int a[N]; //存储每一个数 5 int q[N]; //不同长度的上升子序列结尾的最小值 6 int main() { 7 int n; 8 cin >> n; 9 for (int i = 0; i < n; i++) { 10 cin >> a[i]; 11 } 12 int len = 0; //最大长度,也就是q里面的元素个数 13 //注意:我们要在q数组中二分出来小于某个数的最大的数 14 //为了保证数组当中小于某个数的数一定存在,设置一个哨兵 15 //这个哨兵一定要小于所有数 16 q[0] = -2e9; //这是哨兵 17 for (int i = 0; i < n; i++) { 18 int l = 0, r = len; 19 //在这个范围之间找到小于a[i]的最大的数 20 while (l < r) { 21 int mid = (l + r + 1) / 2; 22 if (q[mid] < a[i]) { //说明我们要找到的答案在mid以及mid右边 23 l = mid; 24 } else { 25 r = mid - 1; 26 } 27 } 28 //二分出的l,r就是可以接在哪个长度后面 29 len = max(len, l + 1); //更新最大值 30 q[l + 1] = a[i]; //更新下一个数 31 } 32 cout << len << endl; 33 return 0; 34 }
也可以用库函数来写
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 100010; 4 int a[N]; 5 int main() { 6 int n; 7 cin >> n; 8 for(int i = 0; i < n; i++) { 9 cin >> a[i]; 10 } 11 vector<int> v; 12 for(int i = 0; i < n; i++) { 13 vector<int>::iterator it = lower_bound(v.begin(), v.end(), a[i]); 14 //lower_bound(val):返回容器中第一个值【大于或等于】val的元素的iterator位置。 15 //upper_bound(val):返回容器中第一个值【大于】val的元素的iterator位置。 16 if (it == v.end()) { 17 v.push_back(a[i]); 18 } else { 19 *it = a[i]; 20 } 21 cout << "i: " << i << endl; 22 for (int i = 0; i < v.size(); i++) { 23 cout << v[i] << " "; 24 } 25 cout << endl; 26 } 27 cout << v.size() << endl; 28 return 0; 29 }