UESTC 1006 最长上升子序列

来源:互联网 发布:淘宝无线端装修 编辑:程序博客网 时间:2024/06/11 09:02

题目链接: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;}
原创粉丝点击