题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159
Common Subsequence
Problem Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, …, xm> another sequence Z = <z1, z2, …, zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, …, ik> of indices of X such that for all j = 1,2,…,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
题目大意:题意很简单,就是给你两个字符串,求他们两个的最长公共子序列。
解题思路:比赛时遇到的一道题,硬是没憋出来。自己的动态的规划这方面还是很渣,看的懂题解却用不来。下来好好学习了别人的方法,这题属于dp中比较基础的题。代码也很短,但思路却很不错,想通了就觉得很妙,想不通就很难受。
用一个二维数组来存储最大公共子序列的长度,一个双重循环,来遍历两个串。当遇到相同字符时就把就将图中该位置左上角的数加一赋给当前位置。如果不相同就比较i-1和j-1位置的值,保留最大的赋给当前位置。这样一直递推到两个字符串结束,最后一个位置存的必定为最长。
#include<cstdio>
#include<cstring>
int Max(int x, int y)
{
if(x > y)
return x;
else
return y;
}
int main()
{
int dp[500][500];
char a[500];
char b[500];
while(~scanf("%s%s", a, b))
{
memset(dp, 0, sizeof(dp));
for(int i = 0; i < strlen(a) + 1; ++i)
for(int j = 0; j < strlen(b) + 1; ++j)
{
if(i == 0 || b == 0)
continue;
if(a[i - 1] == b[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = Max(dp[i - 1][j], dp[i][j - 1]);
}
/* for(int i = 0; i <= strlen(a) + 1; ++i)
{
for(int j = 0; j <= strlen(b) + 1; ++j)
printf("%d ", dp[i][j]);
printf("\n");
}*/
printf("%d\n", dp[strlen(a)][strlen(b)]);
}
return 0;
}