最近一直在学习算法,基本上都是在学习动态规划以及字符串。当然,两者交集最经典之一则是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. JavaScript---网络编程(9-1)--DHTML技术演示(2-1)-表格创建的几种方式

    一:用最底层的方式,该方式用来创建别的对象树也可以 代码演示: <html> <head> <title>DHTML技术演示---表格创建--用最底层的方式,其实该 ...

  2. Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

    2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] D ...

  3. How I Mathematician Wonder What You Are! - POJ 3130(求多边形的核)

    题目大意:判断多多边形是否存在内核. 代码如下: #include<iostream> #include<string.h> #include<stdio.h> # ...

  4. Intellij 中的git操作 转!

    http://blog.csdn.net/lovesummerforever/article/details/50032937 Git原理以后会分章节介绍,本次主要说一下intellij怎样操作git ...

  5. CUDA8.0+VS2013的安装和配置

    首先声明,本文借鉴自:http://blog.csdn.net/u011314529/article/details/51505029 所以,可参考链接的博文.但原文有个瑕疵就是,cublas.lib ...

  6. Android五大布局重新回顾

  7. 安卓开发中Theme.AppCompat.Light的解决方法

    styles.xml中<style name="AppBaseTheme" parent="Theme.AppCompat.Light">提示如下错 ...

  8. 使用OpenXML将Excel内容读取到DataTable中

    前言:前面的几篇文章简单的介绍了如何使用OpenXML创建Excel文档.由于在平时的工作中需要经常使用到Excel的读写操作,简单的介绍下使用 OpenXML读取Excel中得数据.当然使用Open ...

  9. hadoop错误ERROR namenode.NameNode (NameNode.javamain(1657)) - Failed to start namenode java.net.BindException:Port in use:host1:50070

    解决方法: 1.通过lsof -i:50070(lsof可以通过yum install lsof安装)查看,发现是mysql被占用了 2.修改mysql端口 从/usr/share/mysql/my- ...

  10. 怎样通过ajax提交数据

    ajax的出现彻底改变了javascript命运,通过ajax可以直接向服务器提交数据,有两种方式: get方式,数据直接拼接在地址中 post方式,数据由data字段携带 post方式,data中是 ...