题目链接:http://noi.openjudge.cn/ch0206/1808/
描述我们称序列Z = < z 1, z 2, ..., z k >是序列X = < x 1, x 2, ..., x m >的子序列当且仅当存在 严格上升 的序列< i 1, i 2, ..., i k >,使得对j = 1, 2, ... ,k, 有x ij = z j。比如Z = < a, b, f, c > 是X = < a, b, c, f, b, c >的子序列。现在给出两个序列X和Y,你的任务是找到X和Y的最大公共子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列。
输入输入包括多组测试数据。每组数据包括一行,给出两个长度不超过200的字符串,表示两个序列。两个字符串之间由若干个空格隔开。输出对每组输入数据,输出一行,给出两个序列的最大公共子序列的长度。样例输入
abcfbc abfcab programming contest abcd mnp样例输出
4 2 0
较之之前的那个,这个明显更难一点,dp痕迹明显。
ac:
#include<stdio.h>
#include<string.h>
#include<math.h>
//#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define da 0x3f3f3f3f
#define xiao -0x3f3f3f3f
#define clean(a,b) memset(a,b,sizeof(a))// 雷打不动的头文件
int dp[250][250];
char s1[250],s2[250];
int maxx(int a,int b)
{
return a>b?a:b;
}
int main()
{
while(cin>>s1>>s2)
{
int l1=strlen(s1);
int l2=strlen(s2);
int i,j;
clean(dp,0);
for(i=0;i<l1;++i)
{
for(j=0;j<l2;++j)
{//对于每个 字符,相等则下一个位置长度公共串长度+1
if(s1[i]==s2[j])
dp[i+1][j+1]=dp[i][j]+1;
else//不想等则继续遍历所有的字符,刷新最长的长度
dp[i+1][j+1]=maxx(dp[i][j+1],dp[i+1][j]);
}
}
cout<<dp[l1][l2]<<endl;//终点的最长;
clean(s1,'\0');
clean(s2,'\0');
}
}