在写题解之前给自己打一下广告哈~。。抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下:
http://edu.csdn.net/course/detail/209
题目:
Common Subsequence |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
Total Submission(s): 976 Accepted Submission(s): 538 |
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 |
Source
Southeastern Europe 2003
|
Recommend
Ignatius
|
题目分析:
简单DP。求最长公共子序列的长度(Longest Common Sequence,LCS)。其实使用DP的思想在求LCS的时候,使用的还是暴力的思想。遍历两个字符串中的每一个字符,并且判断它们是否相同。这道题需要明白以下两点:
1)状态转移方程
2)使用回溯法求LCS的过程
对于动态规划题的一些整理可以参考一下:http://blog.csdn.net/hjd_love_zzt/article/details/26979313
代码如下:
/* * b.cpp * * Created on: 2015年2月6日 * Author: Administrator */ #include <iostream> #include <cstdio> #include <cmath> using namespace std; const int maxn = 1005; char a[maxn]; char b[maxn]; int c[maxn][maxn]; int get(int i,int j){ if(i >= 0 && j >= 0){ return c[i][j]; } return 0; } int main(){ while(scanf("%s %s",&a,&b)!=EOF){ int n = strlen(a); int m = strlen(b); memset(c,0,sizeof(c));//c[i][j]表示的是a序列的前i个字符与b序列的前j个字符所形成的最长公共子序列的最大长度 int i; int j; for(i = 0 ; i < n ; ++i){ for(j = 0 ; j < m ; ++j){ if(a[i] == b[j]){//判断a序列中的第i个字符和b序列中的第j个字符是否相同 /** * 如果相同,则a序列中的前i个字符和b序列中的前j个字符的最长公共子序列的长度== * a序列中的前i-1个字符和b序列中的前j-1个字符的最长公共子序列的长度 + 1(加1是因为最后一个字符相同,所以最长公共子序列的长度+1) */ c[i][j] = get(i-1,j-1) + 1; }else{//如果a序列的第i个字符和b序列的第j个字符不相同 /** * a序列的前i个字符和b序列的前j个字符所形成的最长公共子序列的长度是 * 1)前i-1个字符与前j个字符所形成的最长公共子序列的长度 * 2)前i个字符与前j-1个字符所形成的最长公共子序列的长度 * 中的较大值 */ c[i][j] = max(get(i-1,j),get(i,j-1)); } } } printf("%d\n",c[n-1][m-1]);//这里为什么输出的索引是n-1和m-1呢。因为索引是从0开始的.n-1已经是最后一个字符的索引 } return 0; }