1002 Problem B
题意:求出两个字符串的公共子序列长度最大值。
思路:最大公共子序列长度,关键是判断当前字符是否相等,如果相等,那么dp[i][j]=dp[i-1][j-1]+1;如果不相等,那么dp[i][j]=max(dp[i-1][j],dp[i][j-1]);(其中dp[i][j]为当前最大公共子序列的长度)
感想:不久前查了一下,关于最大子序列的问题,设有二维数组 f[i][j]表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有:
f[1][1] = same(1,1)
f[i][j] = max{f[i-1][j-1] + same(i,j),f[i-1][j],f[i][j-1]}
其中,same(a,b)当 X 的第 a 位与 Y 的第 b 位完全相同时为“1”,否则为“0”。
此时,f[i][j]中最大的数便是 X 和 Y 的最长公共子序列的长度,依据该数组回溯,便可找出最长公共子序列。
方法比较固定,判断问题的转折,然后套公式即可。
#include<iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;
char x[2000];
char y[2000];
int dp[2000][2000];
int main(){
intj,i,lenx,leny;
cin>>j;
while(scanf("%s%s",x,y)!= EOF){
memset(dp,0,sizeof(dp));
lenx=strlen(x); leny=strlen(y);
for(i=1;i<=lenx;i++)
for(j=1;j<=leny;j++){
if(x[i-1]==y[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
cout<<dp[lenx][leny]<<endl;
}
return 0;
}