最近一直在学习算法,基本上都是在学习动态规划以及字符串。当然,两者交集最经典之一则是LCS问题。

首先LCS的问题基本上就是在字符串a,b之间找到最长的公共子序列,比如 YAOLONGBLOG 和 YCLPBPG,其最长公共子序列则是YLBG

当然当字符串比较大时候,枚举则略显困难。

首先我们先考虑求一个基本问题,就是LCS的长度。

很容易可以理解递推式:

当a[i]==b[j],c[i][j]=c[i-1][j-1]+1;

当a[i]!=b[j], c[i][j]=max(c[i-1][j],c[i][j-1]);

对应HDU1159.

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

这就是裸题啦。利用上面的递推式很容易就写到一个简单的程序。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define MAX 1000
int c[MAX][MAX]; int LCS(string a,string b){
int n=a.length();
int m=b.length();
memset(c,0,sizeof(c));
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
if(a[i-1]==b[j-1]){
c[i][j]=c[i-1][j-1]+1;
}else {
c[i][j]=c[i][j-1]>c[i-1][j]?c[i][j-1]:c[i-1][j]; }
}
return c[n][m]; }
int main(){
string a,b;
while(cin>>a>>b){ cout<<LCS(a,b)<<endl;
} return 0; }

不过为了体现CPP的模板作用,我还写了另外一个版本,不过没有写成HDU1159的题解,只是一个LCS的实现。

/*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date : 2014-03-197
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/ #include <iostream>
#include <string>
#include <cstring>
using namespace std; int max(int a,int b){
return a>b?a:b;
}
template<typename Iterator>
int * lcsLength(Iterator x,Iterator y,int m,int n){
int *c=new int[(m+1)*(n+1)],i,j;
for(i=1;i<=m;i++)
c[i*(n+1)]=0;
for(j=0;j<=n;j++)
c[j]=0;
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
if(*(x+i-1)==*(y+j-1))
c[i*(n+1)+j]=c[(i-1)*(n+1)+j-1]+1;
else c[i*(n+1)+j]=max(c[(i-1)*(n+1)+j],c[(i)*(n+1)+j-1]);
return c; }
template<typename Iterator>
void printLCS(int *c,int n,Iterator x,Iterator y,int i,int j){
if(i==0||j==0) return;
if( *(x+i-1)==*(y+j-1) ){
printLCS(c,n,x,y,i-1,j-1);
cout<<*(x+i-1);
}else if(c[(i-1)*(n+1)+j]>=c[i*(n+1)+j-1])
printLCS(c,n,x,y,i-1,j);
else printLCS(c,n,x,y,i,j-1); }
int main(){ char *x="ACCGGTCGAGTGCGCGGAAGCCGGCCGAA",
*y="GTCGTTCGGAATGCCGTTGCTCTGTAAA";
int *c;
int n=strlen(x),m=strlen(y); c=lcsLength(x,y,n,m);
printLCS(c,m,x,y,n,m);
cout<<endl<<c[ n*(m+1)+m]<<endl;
delete []c; return 0;
}

LCS最长公共子序列HDU1159的更多相关文章

  1. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

  2. POJ 1458 Common Subsequence(LCS最长公共子序列)

    POJ 1458 Common Subsequence(LCS最长公共子序列)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?c ...

  3. 动态规划模板2|LCS最长公共子序列

    LCS最长公共子序列 模板代码: #include <iostream> #include <string.h> #include <string> using n ...

  4. LCS 最长公共子序列

    区别最长公共子串(连续) ''' LCS 最长公共子序列 ''' def LCS_len(x, y): m = len(x) n = len(y) dp = [[0] * (n + 1) for i ...

  5. LCS最长公共子序列(最优线性时间O(n))

    这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...

  6. LCS最长公共子序列

    问题:最长公共子序列不要求所求得的字符串在所给字符串中是连续的,如输入两个字符串ABCBDAB和BDCABA,字符串BCBA和BDAB都是他们的公共最长子序列 该问题属于动态规划问题 解答:设序列X= ...

  7. 动态规划---最长公共子序列 hdu1159

    hdu1159 题目要求两个字符串最长公共子序列, 状态转换方程   f[i][j]=f[i-1][j-1]+1; a[i]=b[j]时 f[i][j]=MAX{f[i-1][j],f[i][j-1] ...

  8. POJ 2250(LCS最长公共子序列)

    compromise Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Descri ...

  9. LCS最长公共子序列~dp学习~4

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 Palindrome Time Limit: 4000/2000 MS (Java/Others ...

随机推荐

  1. List迭代循环时出现分问题

    一个List,通过迭代之后给List中的实体重新赋值,代码如下 public List getListByPage(Page currPage) { Map recordTypeMap = BusnD ...

  2. 斐波那契fib

    输入N和N个数(N<=10,每个数<=10^17),对于每个数,要输出能用几个斐波那契数加加减减得到 样例输入: 35101070 样例输出: 124 直接拷题解: fib[i]表示斐波那 ...

  3. hdu 4712 (随机算法)

    第一次听说随机算法,在给的n组数据间随机取两个组比较,当随机次数达到一定量时,答案就出来了. #include<stdio.h> #include<stdlib.h> #inc ...

  4. typeahead使用配置参数。

    示例代码: var suggestion_source = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace( ...

  5. way/XMPP

    http://git.oschina.net/way/XMPP

  6. win2003 安装itunes ----iphone4s

    工具包下载:http://download.csdn.net/detail/trassion/5852663 在windows 2003 上安装itunes 8.2.0.10 ,会提示 AppleMo ...

  7. Win8.1 与 pl2303驱动

    在8.1上最新的pl2303驱动都不支持Win8.1了.要使用老的驱动 http://www.drv5.cn/sfinfo/9385.html 这里这个驱动里面有五个文件,通过在设备管理器里面查看串口 ...

  8. android本地定时通知

    android本地通知略有不同,分为立即触发和延时触发 1.即时通知 android默认的Notification为立即触发 Intent intent = new Intent(Intent.ACT ...

  9. ashx+html+ajax

    HTML: $(function() { ajax("NewsList.ashx", function(resText) { document.getElementById(&qu ...

  10. 程序员带你十天快速入门Python,玩转电脑软件开发(三)

    声明:本次教程主要适用于已经习得一门编程语言的程序员.想要学习第二门语言.有梦想,立志做全栈攻城狮的你 . 如果是小白,也可以学习本教程.不过可能有些困难.如有问题在文章下方进行讨论.或者添加QQ群5 ...