HDU1159 Common Subsequence(最长公共子序列LCS)
来源:互联网 发布:php框架排行 yii 编辑:程序博客网 时间:2024/06/14 17:30
题目:
Common Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 36328 Accepted Submission(s): 16630
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.
abcfbc abfcabprogramming contest abcd mnp
420
给了两个字符串,求最长公共子序列,最长公共子序列的递推式为
求两字符序列的最长公共字符子序列
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj。例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。
考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:
(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;
(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;
(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。
这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。
上面的分析过程是不是有点看不懂,我在这里用大白话简单地说一下,先给出三个序列,A、B序列分别代表第一和第二个字符串,字符串Z代表它们两个的最长公共子序列,分三种情况:
①:当A序列和B序列的最后一项相等时,则Z的最后一项和A与B的最后一项相等,则它们的最长公共子序列(以下文用LCS来表示)z的第一项到z的的倒数第二项,是A和B的从它们的第一项到它们的倒数第二项的一个LCS。
②:当A的最后一项不等于B的最后一项且Z的最后一项不等于A的最后一项,表示从Z的第一项起到Z的最后一项是从A的第一项起到A的倒数第二项和从B的第一项起到B的倒数第一项的一个LCS.
③:当A的最后一项不等于B的最后一项且Z的最后一项不等于B的最后一项,表示从Z的第一项起到Z的最后一项项是从A的第一项起到A的倒数第一项和从B的第一项起到B的倒数第二项的一个LCS.
按照上面的结论,我们可以从后面往前递推,最后得到递推式(参考上面的图)
求解:
引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。
代码:
#include <stdio.h>#include <string.h>#include <string>#include <iostream>#include <stack>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;char a[2000],b[2000];int dp[2000][2000];//dp[i][j]表示匹配到a字符串的第i个字符和b字符串的第j个字符时的最大匹配数int main(){ while(~scanf("%s%s",a,b)) { int lena=strlen(a); int lenb=strlen(b);//计算长度 for(int i=0; i<=lena; i++) dp[i][0]=0;//初始化边界 for(int i=0; i<=lenb; i++) dp[0][i]=0; for(int i=1; i<=lena; i++) { for(int j=1; j<=lenb; j++) { 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]); } } printf("%d\n",dp[lena][lenb]); } return 0;}
- HDU1159 Common Subsequence(最长公共子序列LCS)
- Common Subsequence hdu1159 最长公共子序列
- 最长公共子序列:HDU1159 Common Subsequence
- HDU1159 Common Subsequence 最长公共子序列
- hdu1159 Common Subsequence (最长公共子序列)
- hdu1159 Common Subsequence(最长公共子序列)
- 最长公共子序列(Longest Common Subsequence LCS)
- 最长公共子序列(Longest-Common-Subsequence,LCS)
- uva10405 - Longest Common Subsequence(LCS,最长公共子序列)
- HD1159 Common Subsequence 最长公共子序列(LCS)
- poj1458-Common Subsequence(最长公共子序列,LCS)
- 最长公共子序列LCS(The longest common subsequence)
- Common Subsequence(LCS最长公共子序列)
- 最长公共子序列问题(LCS) Longest common subsequence
- 最长公共子序列问题(Longest common subsequence,LCS)
- LCS(Longest Common Subsequence 最长公共子序列)
- POJ 1458 Common Subsequence 最长公共子序列(LCS)
- hdu1159 - Common Subsequence (dp 最长公共子序列问题)
- TODO:字节序的一些理解
- 系统重置密码
- 统计学常用的概念
- 当spfile文件中的参数修改错误,导致数据库无法启动问题
- 简单线段树模板
- HDU1159 Common Subsequence(最长公共子序列LCS)
- isstringstream——WOW!Amazing!
- c++ 异常处理(1)
- Hibernate中1+N问题以及解决方法
- 哈理工OJ 2305 Reversed Word(文字翻转stack)
- insmod: error inserting '***.ko': -1 Invalid parameters 真正原因以及解决方法
- 微信小程序-出现脚本错误或者未正确调用 Page()
- Oracle数据库动态注册和参数local_listener的使用
- box-shadow如何显示在它后面元素上面?