题目大意:
一个序列的子序列为原序列去掉若干元素所得的序列(可以去掉0个或全部,空序列也为子序列,去掉的元素可以为原序列中任意位置的元素)。
现有多个测例(测例数无上限),每个测例中给定两个字符串,现求每个测例中两字符串的最长公共子序列的长度。
注释代码:
/*
* Problem ID : POJ 1458 Common Subsequence
* Author : Lirx.t.Una
* Language : C
* Run Time : 0 ms
* Run Memory : 172 KB
*/
#include <string.h>
#include <stdio.h>
//maximum length of string
//经测试字符串最大长度为200
#define MAXSTRLEN 201
#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
typedef unsigned char uc;
char s1[MAXSTRLEN];
char s2[MAXSTRLEN];
//dp[i][j]表示s1中以第i个字符为结尾的字串
//和s2中以第j个字符为结尾的字串
//的最长公共子序列的长度
//范围在uc范围内
uc dp[MAXSTRLEN][MAXSTRLEN];
int
main() {
int len1, len2;//s1、s2的长度
int i, j;
while ( ~scanf("%s%s", s1, s2) ) {
len1 = strlen(s1);
len2 = strlen(s2);
for ( i = 0; i < len1; i++ )
for ( j = 0; j < len2; j++ )
if ( s1[i] == s2[j] )//若末尾相等则表明公共序列长度至少为1
dp[i + 1][j + 1] = dp[i][j] + 1;
else//否则为两个序列分别回退一个字符,取两者中的较大者
dp[i + 1][j + 1] = MAX( dp[i][j + 1], dp[i + 1][j] );
printf("%u\n", dp[len1][len2]);
}
return 0;
}
无注释代码:
#include <string.h>
#include <stdio.h>
#define MAXSTRLEN 201
#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
typedef unsigned char uc;
char s1[MAXSTRLEN];
char s2[MAXSTRLEN];
uc dp[MAXSTRLEN][MAXSTRLEN];
int
main() {
int len1, len2;
int i, j;
while ( ~scanf("%s%s", s1, s2) ) {
len1 = strlen(s1);
len2 = strlen(s2);
for ( i = 0; i < len1; i++ )
for ( j = 0; j < len2; j++ )
if ( s1[i] == s2[j] )
dp[i + 1][j + 1] = dp[i][j] + 1;
else
dp[i + 1][j + 1] = MAX( dp[i][j + 1], dp[i + 1][j] );
printf("%u\n", dp[len1][len2]);
}
return 0;
}
单词解释:
subsequence:n, 子序列,后来放生的事