Greatest Common Increasing Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1353 Accepted Submission(s): 404
Problem Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.
Input
Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.
Output
output print L - the length of the greatest common increasing subsequence of both sequences.
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
Sample Output
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1353 Accepted Submission(s): 404
Problem Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.
Input
Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.
Output
output print L - the length of the greatest common increasing subsequence of both sequences.
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
Sample Output
2
这是一个求最大公共子序列的题目。但是加了一个条件。要求是递增的。。
/*
* DP(最长公共递增非连续子序列Greatest Common Increasing Subsequence)
* 设数组f[i][j]代表第一个序列前i个数与第二个序列前j个数的 最长公共递增非连续子序列(GCIS) 的长度。
* 而数组tmp[i][j]则代表第一个序列前i个数与第二个序列前j个数的GCIS的最大数(即最后一个数)
* max{f[i-1][j-1],f[i-1][j],f[i][j-1]} (当a[i]!=a[j])
* /
* 状态转移方程:f[i][j]=
* \
* max{f[i-1][j-1]+1(满足a[i]>tmp[i-1][j-1]),
f[i-1][j-1],f[i-1][j]+1(满足a[i]>tmp[i-1][j]),
f[i-1][j],f[i][j-1]+1(满足a[i]>tmp[i][j-1]),f[i][j-1]} (当a[i]==a[j])
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#define M 510
using namespace std;
int a[M];
int b[M];
int len[M];
int temp[M];
int lcs(int m,int n)
{
memset(len,0,sizeof(len));
len[0]=-1;
int local=0;
for(int i=1;i<=m;i++)
{
local=0;
for(int j=1;j<=n;j++)
{
if(a[i]>b[j]&&len[j]>len[local])
{
local=j;
}
if(a[i]==b[j])
{
len[j]=max(len[local],0)+1;
}
}
}
int max=-1;
int t=0;
for(int i=1;i<=n;i++)
{
if(max<len[i])
{
max=len[i];
t=i;
}
}
cout<<max<<endl;
return t;
}
void out(int t)
{
int i=1;
int j=t;
temp[i]=b[j];
while(j>=1)
{
j--;
while(j>=1&&len[j]+1!=len[t])j--;
if(j>=1)
{
temp[++i]=b[j];
t=j;
}
}
for(;i>=1;i--)
{
printf("%d ",temp[i]);
}
cout<<endl;
}
int main()
{
freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
int m,n;
cin>>m;
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
}
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
out(lcs(m,n));
if(t)cout<<endl;
}
return 0;
}