在写题解之前给自己打一下广告哈~。。抱歉了,希望大家多多支持我在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. |
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; }