问题描述
给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。
输入格式
输入第一行给出正整数 N N N,第二行给出 N N N个整数,其间以空格分隔。
输出格式
在一行中输出第一次出现的最长连续递增子序列,数字之间用空格分隔,序列结尾不能有多余空格。
输入样例
15
1 9 2 5 7 3 4 6 8 0 11 15 17 17 10
输出样例
9
1 2 3 4 6 8 11 15 17
解题思路
测试代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
size_t n;
cin >> n;
vector<int> a(n);
for(size_t i=0;i<n;i++){
cin >> a[i];
}
vector<size_t> t(n);
size_t m = 1;
t[0] = 1;
for(size_t i=1;i<n;i++){
size_t g = 1;
for(size_t j=0;j<i;j++){
if(a[j]<a[i]){
g = max(g,t[j]+1);
}
}
t[i] = g;
m = max(m,g);
}
cout << m << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
size_t n;
cin >> n;
vector<int> a(n);
for(size_t i=0;i<n;i++){
cin >> a[i];
}
vector<size_t> t(n); /// 动态规划数组
vector<size_t> p(n); /// 用于生成序列,a[i]若为LIS中的一个元素,则p[i]记录了a[i]在LIS中前一个元素的位置
size_t m = 1; /// 记录LIS的长度
size_t k = 0; /// 记录序列最后一个元素的位置
t[0] = 1;
p[0] = 0;
for(size_t i=1;i<n;i++){
size_t g = 1; /// 记录前方各LIS与a[i]构成的最长的长度,若无法与前方构成LIS则自己构成一个长度为1的LIS
size_t r = i; /// 记录前方最长LIS的最后一个元素所在的位置,若无法与前方构成LIS则记录自己的位置
for(size_t j=0;j<i;j++){
if(a[j]<a[i]){
if(g<t[j]+1){
g = t[j]+1;
r = j;
}
}
}
t[i] = g;
p[i] = r;
if(m<g){
m = g;
k = i;
}
}
cout << m << endl;
stack<int> s;
for(;p[k]!=k;k=p[k]){ /// 根据p中的数据,逆推出整个序列
s.push(a[k]);
}
s.push(a[k]); /// 由前方关于变量r的定义可知,序列的第一个元素在p[i]存储的是自己的位置
cout << s.top();
s.pop();
while(!s.empty()){
cout << ' ' << s.top();
s.pop();
}
cout << endl;
return 0;
}