LCS最长公共子序列HDU1159
最近一直在学习算法,基本上都是在学习动态规划以及字符串。当然,两者交集最经典之一则是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.
..., 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.
abcfbc abfcab
programming contest
abcd mnp
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的更多相关文章
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- POJ 1458 Common Subsequence(LCS最长公共子序列)
POJ 1458 Common Subsequence(LCS最长公共子序列)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?c ...
- 动态规划模板2|LCS最长公共子序列
LCS最长公共子序列 模板代码: #include <iostream> #include <string.h> #include <string> using n ...
- LCS 最长公共子序列
区别最长公共子串(连续) ''' LCS 最长公共子序列 ''' def LCS_len(x, y): m = len(x) n = len(y) dp = [[0] * (n + 1) for i ...
- LCS最长公共子序列(最优线性时间O(n))
这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...
- LCS最长公共子序列
问题:最长公共子序列不要求所求得的字符串在所给字符串中是连续的,如输入两个字符串ABCBDAB和BDCABA,字符串BCBA和BDAB都是他们的公共最长子序列 该问题属于动态规划问题 解答:设序列X= ...
- 动态规划---最长公共子序列 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] ...
- POJ 2250(LCS最长公共子序列)
compromise Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Descri ...
- LCS最长公共子序列~dp学习~4
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 Palindrome Time Limit: 4000/2000 MS (Java/Others ...
随机推荐
- 获取和设置select和checkbox的值
if ($("input[name = 'recpower']").prop("checked") == true) //获取checkbox值 { data. ...
- java基础(十五)集合(二)
这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...
- SSL 通信及 java keystore 工具介绍
http://www.javacodegeeks.com/2014/07/java-keystore-tutorial.html Table Of Contents 1. Introduction 2 ...
- mysql 插入默认值的问题 sql-mode
刚好碰到如果不给默认值mysql数据就插入不成功的问题,后来百度了很多,试了下结果 把my.ini里面的[mysqld]的sql-mode 换成下面的一行,如果没有则添加 sql-mode=&quo ...
- BA - 读书雷达10本必读书
https://www.douban.com/doulist/43172796/ 用户故事与敏捷方法 入门篇之一: “是每个ThoughtWorks BA都读的经典入门书籍,详细介绍了用户故事及实用操 ...
- POJ 3734
题目的大意: 给定待粉刷的n个墙砖(排成一行),每一个墙砖能够粉刷的颜色种类为:红.蓝.绿.黄, 问粉刷完成后,红色墙砖和蓝色墙砖都是偶数的粉刷方式有多少种(结果对10007取余). 解题思路: 思路 ...
- Jafka来源分析——文章
Kafka它是一个分布式消息中间件,我们可以大致分为三个部分:Producer.Broker和Consumer.当中,Producer负责产生消息并负责将消息发送给Kafka:Broker能够简单的理 ...
- 最简单的基于FFMPEG的视频编码器(YUV编码为H.264)
本文介绍一个最简单的基于FFMPEG的视频编码器.该编码器实现了YUV420P的像素数据编码为H.264的压缩编码数据.编码器代码十分简单,可是每一行代码都非常重要,适合好好研究一下.弄清楚了本代码也 ...
- C和指针 (pointers on C)——第四章:语句(上)
第四章--语句(上) 总结总结!!! C没有布尔类型,所以在一些逻辑推断时候必须用整型表达式,零值为假,非零值为真. for比while把控制循环的表达式收集起来放在一个地方,以便寻找. do语句比w ...
- activity-intent-startActivity-startActivityResult
一. Intent和startActivity 1.在一个Activtiy中可以使用startActivity()去开始另一个制定的Activity 但在android3.0(是针对平板出的产品)之后 ...