[algorithm]求最长公共子序列问题
最直白方法:时间复杂度是O(n3), 空间复杂度是常数
reference:http://blog.csdn.net/monkeyandy/article/details/7957263
/**
** copyright@andy
** http://blog.csdn.net/MonkeyAndy
**/
首先介绍动态规划方法的相关知识
动态规划方法的基本思想:
分成若干个子问题,先求解子问题,然后根据子问题的解求得原问题的解。经分解得到的子问题往往不是互相独立的。可重复利用!
其核心思想就是分治,分治方法的特点是分解后的子问题相对独立,可以通过简单的合并算法得到原问题的解!
动态规划方法的应用对象:
优化问题:
- 一个优化问题可能有很多可行解,每个解都有一个求解代价,
- 我们希望选择一个具有最少代价的解。
- 一个优化问题可能有多个优化解。
动态规划方法:
当一个优化问题可分为多个子问题,子问题的解在构造上一级问题的求解过程中被重复使用。 这样可以节省计算时间与空间。
动态规划算法的步骤:
- 分析优化解的结构
- 递归地定义最优解的代价
- 自底向上地计算优化解的代价保存之,并获取构造最优解的信息。
- 根据计算优化解的代价,构造优化解
2. 具有重叠子问题(Overlapping sub-problems)
动态规划算法利用该性质,以求得的子问题的解保存后,自底向上地,重复利用子问题的解获得上级问题的解,节省空间开销和时间开销。
如果不具备重叠子问题的性质动态规划方法的空间开销和时间开销很大。利用动态规划算法没有意义!
设x=(x1, x2, ... xm)是一个序列, z=(z1, z2, ... zm) 是x的一个子序列,如果存在1i1<i2<...<ik<m, 使xij=zj
z=(z1, z2, ... zm)即是x=(x1, x2, ... xm)中删除一些元素以后得到的序列。
2.公共子序列定义
Z是序列X与Y的公共子序列,如果Z是X的子序列且Z是Y的子序列。
3.最长公共子序列问题(LCS)
输入:X=(x1, x2, ... xn),Y=(y1, y2, ...ym)
输出:X与Y的最长公共子序列Z
定义. 设X=(x1 , x2 , ... xn) 是一个序列, Xi表示X的第i个前缀,即 Xi=(x1 , ... xi )。
例. X=(A,B,D,C,A), X1=(A), X2=(A,B), X3=(A,B,D)
定理1(LCS的优化结构)设X=(x1 , ... xm), Y=(y1 , y2 , ... yn)是两个序列,Z=(z1 , z2 , ... zk) 是X与Y的LCS。下列结论成立:
- 如xm= yn, 则zk=xm=yn, Zk-1是Xm-1和Yn-1的LCS,即,LCS(X,Y)=LCS(Xm-1,Yn-1)+xm
- 若xm != yn,且zk!=xm,则Z是Xm-1和Y的LCS,即 LCS(X,Y)=LCS(Xm-1,Y)
- 若xm != yn , 且zk !=yn,则Z是X与Yn-1的LCS,即 LCS(X,Y)=LCS(X,Yn-1)
If xm !=yn , 必须求解Xm-1和Y的LCS以及X和Yn-1 的LCS,长者是X和Y的LCS。C[i,j] 表示Xi与Yj的LCS的长度,则建立求解LCS长度的递归方程
1.基本思想
计算C[i,j] 需先计算C[i-1,j-1]、C[i,j-1]、C[i-1,j]
| C[i-1,j-1] | C[ i, j-1] |
| C[i-1, j] | C[ i, j] |
先计算出第0行与第0列,然后逐行计算。
2. 算法
- /**
- *copyright@andy
- *date@ 2012/09/08
- * m : x的长度
- * n : y的长度
- * c : xi与yi的LCS的长度
- * b : 用于标记xi和yi的关系
- **/
- void LCSLength( int m, int n, char *x, char *y int **c, Type **b )
- {
- int i, j;
- /*c 初始化*/
- for ( i=1; i<=m; i++) c[ 0 ][ i ]=0;
- for( j=1; j<=n, j++) c[ j ][0 ]=0;
- for ( i=1; i<=m; i++)
- for( j=1; j<=n, j++)
- {
- if(x[i]==y[j]) //xi = yj 时LCS 增1
- {
- c[ i ][ j ]=c[ i-1 ][ j-1]+1;
- b[ i ][ j ]='\'';
- }
- else if ( c[i-1][j] >= c[i][j-1]) //当xi ≠ yj时保存长子序列
- {
- c[ i ][ j ]=c[ i-1 ][ j];
- b[ i ][ j ]='|';
- }
- else
- {
- c[ i ][ j ]=c[ i ][ j-1];
- b[ i ][ j ]='--';
- }
- }
- }
- /**
- *copyright@andy
- *date@ 2012/09/08
- * i : x的长度
- * j : y的长度
- * x : x字符串
- * b : 用于标记xi和yi的关系
- **/
- void LCS( int i, int j, char *x, Type **b )
- {
- if ( i==0 || j==0) return;
- if (b[ i ][ j ] =='\'')//当xi = yj 时,输出xi ,并删除xi 和 yj ,之后在子序列中继续求解LCS
- {
- LCS(i-1, j-1, x, b);
- out<<x[ i ];
- }
- else if ( b[i][j] == '|')//当Xi-1 和 Yj 的LCS不小于Xi 和 Yj-1 的LCS 时
- LCS(i-1, j, x, b); //在Xi-1 和 Yj中继续求解LCS;否则,在Xi 和 Yj-1 中继续求解LCS;
- else
- LCS( i, j-1, x, b);
- }
[algorithm]求最长公共子序列问题的更多相关文章
- HDU 4681 string 求最长公共子序列的简单DP+暴力枚举
先预处理,用求最长公共子序列的DP顺着处理一遍,再逆着处理一遍. 再预处理串a和b中包含串c的子序列,当然,为了使这子序列尽可能短,会以c 串的第一个字符开始 ,c 串的最后一个字符结束 将这些起始位 ...
- HDU 1243 反恐训练营 (动态规划求最长公共子序列)
反恐训练营 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- Java实现 LeetCode 583 两个字符串的删除操作(求最长公共子序列问题)
583. 两个字符串的删除操作 给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符. 示例: 输入: " ...
- poj1458 求最长公共子序列 经典DP
Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 45763 Accepted: 18 ...
- codevs 1862 最长公共子序列(求最长公共子序列长度并统计最长公共子序列的个数)
题目描述 Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 【dp】求最长公共子序列
[题目描述] 一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X=<x1,x2,…,xm>X=<x1,x2,…,xm>,则另一序列Z=<z1 ...
- Coincidence (动态规划求最长公共子序列)(王道)
题目描述: Find a longest common subsequence of two strings. 输入: First and second line of each input case ...
- hdu 1159求最长公共子序列
题目描述:给出两个字符串,求两个字符串的公共子序列(不是公共子串,不要求连续,但要符合在原字符串中的顺序) in: abcfbc abfcab programming contest abcd mnp ...
随机推荐
- ASP.NET缓存全解析2:页面输出缓存 转自网络原文作者李天平
页面输出缓存是最为简单的缓存机制,该机制将整个ASP.NET页面内容保存在服务器内存中.当用户请求该页面时,系统从内存中输出相关数据,直到缓存数据过期.在这个过程中,缓存内容直接发送给用户,而不必再次 ...
- windowSoftInputMode属性详解
转自:http://blog.csdn.net/twoicewoo/article/details/7384398 activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Andro ...
- VLAN系列
Write From Yangwj Sunday, March 9, 2014 一. Vlan的识别 1. 交换机端口是访问端口,它就属于某一个Vlan:如果是中继端口,它就可以属于所有Vlan. 2 ...
- 第七篇、OC_图片的裁剪基于SDWebImage
前期有段时间困扰了我很久一个问题由于工程中的图片数据抓取自不同平台,所以图片的大小尺寸不一定,而放置图片的imageView尺寸是一定的,不作任何处理的话会导致图片拉伸变形,因此找了好久解决办法,现把 ...
- Firebug 调试技巧之console API
console.log(object[, object, ...]) Writes a message to the console. You may pass as many arguments a ...
- 20141030--SQL2008常用命令-1
create database biao2--创建新的数据库 go use biao2 go create table shuiguo--创建表shuiguo ,create table创建表 ( 序 ...
- 8款超绚丽的jQuery焦点图动画
随着前端技术和浏览器技术的不断发展,人们开始对网页视觉效果的要求越来越高.我们经常会在页面中看到很多炫酷的图片焦点图播放控件,有些甚至是大屏的焦点图占用大片的页面空间,从而吸引用户的眼球.本文要分享的 ...
- hdu 2544 最短路 Dijkstra
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 题目分析:比较简单的最短路算法应用.题目告知起点与终点的位置,以及各路口之间路径到达所需的时间, ...
- NDK 通过java调用so文件
首先我们来看so文件的来源 1. 自己写.c文件,然后生成so库 2. 引用别人的静态库,或者动态库来生成新的jni调用库. 我们先来看最简单的编写一个jni调用的so库,包含一个获取字符串的方法,通 ...
- iframe整理学习笔记
朋友问了一个比较怪的问题,iframe下自适应的问题,因为很少使用iframe的原因,怀着对iframe的疑惑采用了一点点实践;以下frame表示针对的iframe元素 解决的方法:对iframe进行 ...