题目链接:http://acm.uestc.edu.cn/#/problem/show/1006
算法复杂度:O(N^2)
dp[i]表示以第i个元素开头的最长上升子序列长度
for(i=1;i<=n;i++) dp[i]=1;
for(i=n;i>=1;i–)
{
for(j=n;j>i;j–)
if (a[j]>a[i]) dp[i]=max(dp[i],dp[j]+1);
}
找出最大的dp[i]为len
设最长最小上升子序列的第x个元素为r[x],pos(x)为第x个元素的下标
r[x]=min(a[j]) (dp[j]==len+1-x;pos(x-1)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int a[maxn], dp[maxn];
vector <int> v, v2;
int main()
{
int T, n;
scanf("%d", &T);
while(T--){
v.clear();
v2.clear();
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
for(int i=1; i<=n; i++) dp[i]=1;
for(int i=1; i<=n; i++){
for(int j=1; j<i; j++){
if(a[j]<a[i]){
dp[i]=max(dp[i], dp[j]+1);
}
}
}
int mx = 0;
for(int i=1; i<=n; i++) mx = max(mx, dp[i]);
printf("%d ", mx);
for(int i=n; i>=1; i--){
if(dp[i]==mx){
v.push_back(a[i]);
mx--;
}
}
while(!v.empty()){
v2.push_back(v.back());
v.pop_back();
}
for(int i=0; i<(int)v2.size(); i++){
printf("%d ", v2[i]);
}
printf("\n");
}
return 0;
}