poj2127 Greatest Common Increasing Subsequence
时空限制 1000ms/64MB
【题目描述】
You are given two sequences of integer numbers. Write a program to determine their common increasing subsequence of maximal possible length.
Sequence S1 , S2 , . . . , SN of length N is called an increasing subsequence of a sequence A1 , A2 , . . . , AM of length M if there exist 1 <= i1 < i2 < . . . < iN <= M such that Sj = Aij for all 1 <= j <= N , and Sj < Sj+1 for all 1 <= j < N .
给定两个整数序列,写一个程序求它们的最长上升公共子序列。
当以下条件满足的时候,我们将长度N的序列S1,S2,...,SN 称为长度为M的序列A1,A2,...,AM的上升子序列:存在1≤i1<i2<...<iN≤M,使得对所有1≤j≤N,均有Sj=Aij,且对于所有的1≤j<N,均有Sj<Sj + 1。
【输入】
Each sequence is described with M --- its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31 ) --- the sequence itself.
每个序列用两行表示,第一行是长度M(1≤M≤500),第二行是该序列的M个整数Ai(−2^31≤Ai<2^31)
【输出】
On the first line of the output file print L --- the length of the greatest common increasing subsequence of both sequences. On the second line print the subsequence itself. If there are several possible answers, output any of them.
在第一行,输出两个序列的最长上升公共子序列的长度L。在第二行,输出该子序列。如果有不止一个符合条件的子序列,则输出任何一个即可。
【输入样例】
5
1 4 2 5 -12
4
-12 1 2 4
【输出样例】
2
1 4
代码
法一:数组存路径
#include<iostream> //数组存路径
#include<algorithm>
using namespace std;
const int N = 505;
int n,m,a[N],b[N];
struct node{
int len,path[N]; //长度和路径
};
node f[N],maxv;
int main(){
cin>>n;
for (int i=1; i<=n; i++) cin>>a[i];
cin>>m;
for (int i=1; i<=m; i++) cin>>b[i];
for (int i=1; i<=m; i++){ //遍历b
maxv.len=0; fill(maxv.path,maxv.path+N,0);
for (int j=1; j<=n; j++){ //遍历a
if (a[j]<b[i] && f[j].len>maxv.len) maxv=f[j]; //更新时,找len最大值
if (a[j]==b[i]){ //接上a[j]
f[j] = maxv;
f[j].path[++f[j].len] = a[j];
}
}
}
int ans=f[1].len,pos=1;
for (int i=2; i<=n; i++)
if (f[i].len>ans) ans=f[i].len,pos=i;
cout<<ans<<endl;
for (int i=1; i<=f[pos].len; i++)
i<f[pos].len ? cout<<f[pos].path[i]<<" " : cout<<f[pos].path[i]<<endl;
return 0;
}
法二:路径vector优化
#include<iostream> //存路径vector优化
#include<vector>
#include<algorithm>
using namespace std;
const int N = 505;
int n,m,a[N],b[N];
struct node{
int len; //长度
vector<int> path; //路径
};
node f[N],maxv;
int main(){
cin>>n;
for (int i=1; i<=n; i++) cin>>a[i];
cin>>m;
for (int i=1; i<=m; i++) cin>>b[i];
for (int i=1; i<=m; i++){ //遍历b
maxv.len=0; maxv.path.clear();
for (int j=1; j<=n; j++){ //遍历a
if (a[j]<b[i] && f[j].len>maxv.len) maxv=f[j]; //更新时,找len最大值
if (a[j]==b[i]){ //接上a[j]
f[j] = maxv;
f[j].len++;
f[j].path.push_back(a[j]);
}
}
}
int ans=f[1].len,pos=1;
for (int i=2; i<=n; i++)
if (f[i].len>ans) ans=f[i].len,pos=i;
cout<<ans<<endl;
for (int i=0,k=f[pos].path.size(); i<k; i++)
i<k-1 ? cout<<f[pos].path[i]<<" " : cout<<f[pos].path[i]<<endl;
return 0;
}