最长公共上升子序列

【题目描述】

给定两个整数序列,求它们的最长上升公共子序列。

【输入描述】

输入两组数据,每组数据代表一个整数序列,其输入格式为:

第一行输入长度M(1 <= M <= 500);

第二行输入该序列的M个整数Ai(-231 <= Ai < 231)。

【输出描述】

输出共两行。

第一行输出两个序列的最长上升公共子序列的长度L;

第二行输出该子序列,如果有不止一个符合条件的子序列,则输出任何一个即可。

【输入样例】

5

1 4 2 5 -12

4

-12 1 2 4

【输出样例】

2

1 4

源代码:

#include<cstdio>
int m,n,s,num=1,ans(0),h[501],i1[501],i2[501],f[501][501]={0};
int main()
{
    scanf("%d",&m);
    for (int a=1;a<=m;a++)
      scanf("%d",&i1[a]);
    scanf("%d",&n);
    for (int a=1;a<=n;a++)
      scanf("%d",&i2[a]);
    for (int a=1;a<=m;a++)
    {
        int t(0);
        for (int b=1;b<=n;b++)
          if (i1[a]==i2[b])
            f[a][b]=t+1;
          else
          {
              f[a][b]=f[a-1][b]; //正推。
              if (i1[a]>i2[b])
                t=f[a][b]>t?f[a][b]:t;
          }
    }
    for (int a=1;a<=n;a++)
      ans=ans>f[m][a]?ans:f[m][a];
    printf("%d\n",ans);
    if (ans) //非0情况。
    {
        for (int a=n;a>0;a--) //查找源头。
            if (f[m][a]==ans)
            {
              s=a;
              break;
            }
        h[num]=i2[s];
        while (m-1) //逐行查找。
        {
            m--;
            if (f[m][s]!=f[m+1][s])
                for (int a=s-1;a>0;a--)
                  if (f[m][a]==f[m+1][s]-1&&i2[a]<i2[s]&&f[m][a]) //注意,若为0,则不选。
                 {
                     s=a;
                     h[++num]=i2[a];
                     break;
                 }
        }
        for (int a=num;a>0;a--) //任意的一组合法答案。
          printf("%d ",h[a]);
    }
    return 0;
}
posted @ 2016-04-03 10:28  前前前世。  阅读(399)  评论(0编辑  收藏  举报