UVA 10405 - Longest Common Subsequence

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=114&page=show_problem&problem=1346

 

题目大意:

 

                   就是输入两个字符序列,输出两个序列的最长公共子序列(注意序列跟串的区别)。

 

题目类型:

 

               经典dp /LCS

 

分析:

 

             就是 最长公共子序列(LCS)的问题。d[i][j]表示a[i]之前、b[j]之前(含端点)的序列的最大子序列长度,

 

   则状态转移方程:di,j = { di-1,j-1+1, 当a[i]=b[j]; max{di,j-1, di-1,j}, 当a[i]≠b[j]; }。

 

   原问题的解就是 d(len(a)-1, len(b)-1) 了;

 

              注:此题又很恶心,题目描述中没有说输入中有没有空格,结果用scanf WA了,换成gets 当场A了。注意咯。

 

              总结:注意用scanf 读串的时候要小心, 注意与gets的区别!

 

 

代码:

 

#include<cstdio> #include<cstring> using namespace std; #define MAXN 1005 char a[MAXN], b[MAXN]; int d[MAXN][MAXN], vis[MAXN][MAXN]; int lcs(int i, int j) { if(i == -1 || j == -1) return 0; //停止条件 if(vis[i][j]) return d[i][j]; vis[i][j] = 1; if(a[i] == b[j]) return d[i][j] = lcs(i-1, j-1)+1; else return d[i][j] = lcs(i-1, j)>lcs(i, j-1)? lcs(i-1, j): lcs(i, j-1); } int main() { //while(scanf("%s%s", &a, &b) != EOF) //scanf遇空格停止。 while(gets(a) && gets(b)) //gets()的返回值是读入的字符串,如果错误返回NULL. { memset(vis, 0, sizeof(vis)); printf("%d/n", lcs(strlen(a)-1, strlen(b)-1)); } }

 

你可能感兴趣的:(UVA 10405 - Longest Common Subsequence)