最长上升子序列(输出序列)
内存限制: 64 MiB 时间限制: 1000 ms 标准输入输出 题目类型: 传统 评测方式: 文本比较
题目描述
给定一个整数序列 A1,A2,A3,…,An。求它的一个递增子序列,使子序列的元素个数尽量多,元素不一定要求连续。
输入格式
第1行:1个整数 n(1 <= n <= 5000),表示序列中元素的个数.
第2行 - n + 1行:每行 1 个整数 x(-1000 <= x <= 1000),第 i + 1 行表示序列中的第 i 个元素。
输出格式
第1行:1个整数 k,表示最长上升子序列的长度。
第2行:k 个用单个空格分开的整数,表示找到了最长上升子序列。输出的是序列中的元素,并非下标。如果有多个长度等于 k 的子序列,则输出最靠前的 1 个。
样例
样例输入
复制8
1 3 2 4 3 5 4 6
样例输出
复制5
1 3 4 5 6
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
stack<int> s;
int n, e, ans;
int dp[N], num[N], pre[N];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &num[i]);
dp[i] = 1;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j < i; j++) {
if(num[j] < num[i]) {
if(dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
pre[i] = j;
}
}
}
}
for(int i = 1; i <= n; i++) {
if(dp[i] > ans) {
ans = dp[i];
e = i;
}
}
printf("%d\n", ans);
while(e != 0) {
s.push(num[e]);
e = pre[e];
}
while(!s.empty()) {
printf("%d ", s.top());
s.pop();
}
return 0;
}