poj2127 Greatest Common Increasing Subsequence

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<...<iNM,使得对所有1≤jN,均有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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值