这是个经典的动态规划问题,我花了很长时间研究这个问题的算法,而且写了一个O(m*n)的算法,计算速度很快,用很多组测试数据测试都对,可是在POJ上就是Wrong Answer,不知是什么原因,很郁闷!代码贴出来,希望有人能指出为什么总是WA。
此题的状态转移方法如下:f(i,j)表示a[1..i]序列和b[1..j]序列以ai结尾的最长公共子序列的长度。
#include <stdlib.h>
int main()
{
int m,n;
int fff[501][501]={0}; //fff[i][j]表示a[1..i]与b[1..j]以a[i]结尾的最长递增子序列的长度
int a[501]={0};
int b[501]={0};
int path[501]={0}; //记录最长递增子序列的路径
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
int maxLength=0;
int maxPostion=0; //记录最长递增公共子序列最后一个元素的位置
int k;
for(int j=1;j<=n;j++)//一列一列的添
{
k = 0;
for(int i=1;i<=m;i++)
{
if (a[i]==b[j] )
{
fff[i][j]=fff[k][j]+1;//以a[i]结尾的公共子序列长度为以a[k]结尾的公共子序列长度+1
path[i]=k; //公共子序列路径:a[i]的前驱是a[k]
if(fff[i][j]>maxLength)
{
maxLength=fff[i][j];
maxPostion = i;
}
}
else fff[i][j]=fff[i][j-1];
if (a[i]<b[j] && fff[i][j]>fff[k][j])
k=i; //对于每一列,k总是指向比b[j]小且在fff[1..i-1][j]范围内的最大值
}
}
printf("%d\n",maxLength);
int temp[501];
k=0;
for(int i=0;i<maxLength;i++)
{
temp[k++]=maxPostion;
maxPostion=path[maxPostion];
}
if(maxLength>0)
{
for(int i=k-1;i>=0;i--)
printf("%d ",a[temp[i]]);
}
printf("\n");
return 0;
}