Greatest Common Increasing Subsequence poj-1423

来源:互联网 发布:java面对对象 编辑:程序博客网 时间:2024/06/05 19:24


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[]数组存储a[]数组和b[]数组各个点之间所组成的公共递增子序列的个数。

eg1(这里数组的下标从1开始):

   a[] :  1 4 2 5 -12

   b[] :  -12 1 2 4

从a[1]开始遍历b[]数组,看在b[]数组中有多少和a[1]相等的数,将dp[]值加1.

eg2:

a[1]:   

         b[1]=-12  b[2]=1  b[3]=2  b[4]=4

         dp[1]=0  dp[2]=1  dp[3]=0 dp[4]=4

a[2]:

         dp[1]=0  dp[2]=1  dp[3]=0 dp[4]=2

a[3]:

         dp[1]=0  dp[2]=1  dp3]=2  dp[4]=2

a[4]:    

         dp[1]=0  dp[2]=1  dp[3]=2 dp[4]=2

a[5]:

         dp[1]=0  dp[2]=1  dp[3]=3 dp[4]=2

其实就是求在b[]数组中,最大值为a[i]的子序列。


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int main(){    int t,n,m,sum;    int a[5200],b[5200],dp[5200];    scanf("%d",&t);    while(t--)    {        memset(dp,0,sizeof(dp));        scanf("%d",&n);        for(int i=1; i<=n; i++)            scanf("%d",&a[i]);        scanf("%d",&m);        for(int i=1; i<=m; i++)            scanf("%d",&b[i]);        sum=0;        for(int i=1; i<=n; i++)        {            int k=0;            for(int j=1; j<=m; j++)            {                if(a[i]==b[j] && dp[j]<k+1)                    dp[j]=k+1;                else if(a[i]>b[j])                {                    if(dp[j]>k)                        k=dp[j];                }                sum=max(sum,dp[j]);            }        }        printf("%d\n",sum);        if(t)            printf("\n");    }    return 0;}