就是寻找LIS 并打印出来
dp[i]表示到包括第i个数的前i个的最长递增的长度
从数列从后往前找就好了 ,如果从前往后,前面的大数会覆盖掉后面的小数,就不对了
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1e5+10; 5 6 int a[maxn],dp[maxn],ans[maxn]; 7 vector<int> v; 8 9 int main(){ 10 int t; cin>>t; 11 while(t--){ 12 int n; cin >> n; 13 for(int i=1; i<=n; i++) 14 cin >> a[i]; 15 memset(ans,0x3f,sizeof(ans)); 16 memset(dp,0,sizeof(dp)); 17 v.clear(); 18 int mx = -1; 19 for(int i=1; i<=n; i++){ 20 int p = lower_bound(ans+1,ans+1+n,a[i])-ans; 21 ans[p] = a[i]; 22 dp[i] = p; 23 mx = max(mx,p); 24 } 25 26 cout << mx << endl; 27 int k = maxn; 28 for(int i=n; i>=1; i--){ 29 if(dp[i]==mx && a[i]<k){ 30 v.push_back(a[i]); 31 k = a[i]; 32 mx--; 33 } 34 } 35 // int k = -1,cnt=1; 36 // for(int i=1; i<=n; i++){ // 不能正序,前面大的数会覆盖后面小的数 不能达到最长 37 // if(dp[i]==cnt && a[i]>k){ 38 // v.push_back(a[i]); 39 // k = a[i]; 40 // cnt++; 41 // } 42 // } 43 44 for(int i=v.size()-1; i>=1; i--) 45 cout << v[i] << " "; 46 cout << v[0] << endl; 47 } 48 }