看了算法导论公开课第15集,就找了两道题来练习,
可以参考01背包的表格记录方式解决,滚动数组方法还没试,有心情再说~~
方法:
x为长为m的序列,y长为n;
用c[i,j]代表x[1,2,...i]和y[1,2,...j]这两个序列的最长公共子序列(LCS)的长度;
那么c[m,n]即为题目所求;
接下来是递推公式:
哈哈~~
大概就是这样,接下来说这两道题
先说nyoj的吧
。。。
没啥好说的,就是套公式,直接贴代码吧
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int a[1005][1005];
int main()
{
int n;
string addx,addy,x,y;
cin>>n;
while(n--)
{
cin>>addx>>addy;
x=y="0"; x+=addx; y+=addy;
memset(a,0,sizeof(a));
for(int j=1;j!=y.size();++j)
{
for(int i=1;i!=x.size();++i)
{
if(x[i]==y[j])
a[j][i]=a[j-1][i-1]+1;
else
a[j][i]=a[j-1][i]>a[j][i-1]?a[j-1][i]:a[j][i-1];
}
}
cout<<a[y.size()-1][x.size()-1]<<endl;
}
return 0;
}
接下来说UVA的,略纠结
一开始看两道题题意都一样,只是格式略有不同,就把上面的代码改了改,结果就WA了,后来百度看人家的才知道貌似不管用scanf还是cin都不行,有可能是序列中有空格或是什么其他原因,改用gets就可以ac了~
贴代码
#include<cstdio>
#include<cstring>
int c[1005][1005];
char x[1005],y[1005];
int main()
{
while(gets(x+1))
{
gets(y+1);
memset(c,0,sizeof(c));
x[0]=y[0]='0';
int m=strlen(x)-1;
int n=strlen(y)-1;
for(int i=1;i<=m;++i)
{
for(int j=1;j<=n;++j)
{
if(x[i]==y[j]) c[i][j]=c[i-1][j-1]+1;
else c[i][j]=c[i-1][j]>c[i][j-1]?c[i-1][j]:c[i][j-1];
}
}
printf("%d\n",c[m][n]);
}
return 0;
}