您的位置:首页 > 产品设计 > UI/UE

poj 2127 Greatest Common Increasing Subsequence (最长公共递增子序列)

2014-02-11 14:42 579 查看
Greatest Common Increasing Subsequence

Time Limit: 10000MS Memory Limit: 65536K
Total Submissions: 8888 Accepted: 2345
Case Time Limit: 2000MS Special Judge
Description

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 .
Input

Each sequence is described with M --- its length (1 <= M <= 500) and M integer numbers Ai (-231 <= Ai < 231 ) --- the sequence itself.
Output

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.
Sample Input
5
1 4 2 5 -12
4
-12 1 2 4

Sample Output
2
1 4

Source

Northeastern Europe 2003, Northern Subregion
题意:

给出两个序列a、b,求最长公共递增子序列。

思路:

dp[j]表示以b[j]结尾的LCIS的长度。

每次用a[i]去更新dp[j],则

if(a[i]==b[j]) dp[j]=max(dp[j],dp[k]);  (1<=k<j&&b[k]<b[j])

维护好k的值,那么就可以将复杂度降到O(n*m)了。

由于要记录路径,用一维的dp、pre不太好处理,我用的是二维的,递归输出路径。

思路来源:推荐

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 100005
#define mod 100000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

int n,m,k,ans,cnt,tot,flag;
int ai,aj;
int a[505],b[505];
int dp[505][505],px[505][505],py[505][505];

void output(int x,int y,int last)
{
if(x==0||y==0) return ;
output(px[x][y],py[x][y],y);
if(y!=last)
{
cnt++;
if(cnt==1) printf("%d",b[y]);
else printf(" %d",b[y]);
}
}
void solve()
{
int i,j,k,t;
memset(dp,0,sizeof(dp));
memset(px,0,sizeof(px));
memset(py,0,sizeof(py));
ans=0;
for(i=1;i<=n;i++)
{
k=0;
for(j=1;j<=m;j++)
{
dp[i][j]=dp[i-1][j];
px[i][j]=i-1,py[i][j]=j;
if(b[j]==a[i])
{
if(dp[i][j]<dp[i][k]+1)
{
dp[i][j]=dp[i][k]+1;
px[i][j]=i,py[i][j]=k;
}
}
else if(b[j]<a[i])
{
if(dp[i][k]<dp[i][j]) k=j;
}
if(dp[i][j]>ans)
{
ans=dp[i][j];
ai=i,aj=j;
}
}
}
printf("%d\n",ans);
if(ans==0) return ;
cnt=0;
output(ai,aj,-1);
printf("\n");
}
int main()
{
int i,j,t;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d",&b[i]);
}
solve();
}
return 0;
}
/*
7
1 2 4 0 1 4 5
6
0 3 1 2 4 5
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: