【题目描述】
给定两个整数序列,求它们的最长上升公共子序列。
【输入描述】
输入两组数据,每组数据代表一个整数序列,其输入格式为:
第一行输入长度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 ",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; }