一、标准模板

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <set>
#include <cassert>
#include <time.h>
#include <queue>
#include <map>
#include <stack>
#include <bitset>
#include <string>
#include <sstream>
#define INF 0x3f3f3f3f#define PRINT(x) cout<<x<<endl;using namespace std;template <class Type>
Type stringToNum(const string& str)
{istringstream iss(str);Type num;iss >> num;return num;
}//======================================================#define MAXN 205int dp[MAXN][MAXN];int whLCS(char s1[],int len1,char s2[],int len2) {for(int i=1;i<=len1;++i) {for (int j=1;j<=len2;++j) {if(s1[i-1]==s2[j-1])dp[i][j]=dp[i-1][j-1]+1;elsedp[i][j]=max(dp[i-1][j],dp[i][j-1]);}}return dp[len1][len2];
}int main()
{freopen("input.txt","r",stdin);char s1[MAXN],s2[MAXN];while (scanf("%s %s",s1,s2)!=EOF) {int res = whLCS(s1,strlen(s1),s2,strlen(s2));PRINT(res);}return 0;
}

当然,在内存吃紧的情况下可以用所谓的”滚动数组”,因为找子串的时候是一排一排刷的,而关系到的排只会是上一排,这样就只用保存2排就好(交替使用)。

int whLCS(char s1[],int len1,char s2[],int len2) {int rowFlag = 1;for(int i=1;i<=len1;++i) {for (int j=1;j<=len2;++j) {if(s1[i-1]==s2[j-1])dp[rowFlag][j]=dp[!rowFlag][j-1]+1;elsedp[rowFlag][j]=max(dp[!rowFlag][j],dp[rowFlag][j-1]);}rowFlag = !rowFlag;}return dp[!rowFlag][len2];
}

AC code

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <set>
#include <cassert>
#include <time.h>
#include <queue>
#include <map>
#include <stack>
#include <bitset>
#include <string>
#include <sstream>
#define INF 0x3f3f3f3f#define PRINT(x) cout<<x<<endl;using namespace std;template <class Type>
Type stringToNum(const string& str)
{istringstream iss(str);Type num;iss >> num;return num;
}//======================================================#define MAXN 205int same(int a,int b) {return a==b?1:0; //相等返回1
}int MaxOfThree(int a,int b,int c) {return (a>=b && a>=c)?a:((b>=a && b>=c)?b:c);
}int dp[MAXN][MAXN];
int whLCS(char s1[],int len1,char s2[],int len2) {memset(dp,0,sizeof(dp));for(int i=1;i<=len1;i++){for(int j=1;j<=len2;j++){dp[i][j]=MaxOfThree( dp[i-1][j-1]+same(s1[i-1],s2[j-1]) , dp[i-1][j] , dp[i][j-1]); //这里简化判断}}return dp[len1][len2];
}int main()
{//freopen("input.txt","r",stdin);char s1[MAXN],s2[MAXN];while (scanf("%s %s",s1,s2)!=EOF) {int res = whLCS(s1,strlen(s1),s2,strlen(s2));PRINT(res);}return 0;
}

二、问题分析

1、dp

经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。

为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。

2、求解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]。

问题的递归式写成:

回溯输出最长公共子序列的过程:

3、算法分析

由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故算法时间复杂度为Θ(m + n)。


参考资料

[1] http://blog.csdn.net/yysdsyl/article/details/4226630

最长公共子序列 LCS(模板) poj 1458相关推荐

  1. 最长公共子序列 (LCS) 详解+例题模板(全)

    欢迎访问https://blog.csdn.net/lxt_Lucia-- 宇宙第一小仙女\(^o^)/-萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗- ------------ ...

  2. 动态规划算法解最长公共子序列LCS问题

    动态规划算法解LCS问题 作者 July 二零一零年十二月三十一日 本文参考:微软面试100题系列V0.1版第19.56题.算法导论.维基百科. 第一部分.什么是动态规划算法 ok,咱们先来了解下什么 ...

  3. 动态规划之最长公共子序列(LCS)

    最长公共子序列(LCS,Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最 ...

  4. 程序员编程艺术第十一章:最长公共子序列(LCS)问题

    程序员编程艺术第十一章:最长公共子序列(LCS)问题 0.前言 程序员编程艺术系列重新开始创作了(前十章,请参考程序员编程艺术第一~十章集锦与总结).回顾之前的前十章,有些代码是值得商榷的,因当时的代 ...

  5. 算法之最长公共子序列(LCS)问题

    算法课上老师留的作业,最长公共子序列LCS(Longest Common Subsequence)问题,首先看到这个问题感觉有点复杂,和最长公共子串不同,公共子序列并不要求元素相邻,看起来只有穷举才能 ...

  6. 最长公共子序列php,动态规划(最长公共子序列LCS)

    概念 求解决策过程最优化的结果 (可能有多个) 把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解 计算过程中会把结果都记录下,最终结果在记录中找到. 举例 求两个字符串的最长公共子序 ...

  7. python实现求解最长公共子序列LCS问题

    在实现论文<Automatically Generating Models for Botnet Detection>论文的算法中,用到了一个The longest commom subs ...

  8. 算法导论-----最长公共子序列LCS(动态规划)

    目录 一.概念梳理 二.最长公共子序列解决方案 方案1:蛮力搜索策略 方案2:动态规划策略 三.C代码实现 实现1 实现2(空间优化) 一.概念梳理   1. 子序列(subsequence): 一个 ...

  9. 1265:【例9.9】最长公共子序列 LCS 朴素做法O(n*2)

    分析 最长公共子序列的模板题,参考视频:最长公共子序列 - 动态规划: 如果第一个序列的第i个字符,与第二个序列的第j个字符相等时,则i,j这个点的dp值为左上角的dp值+1:否则为,该点上面那个点和 ...

  10. 动态规划表格法解决最长公共子序列(LCS)问题

    3.5 最长公共子序列(LCS) 前言:图片是博主自己画的,转载请注明出处哦 3.5.1 问题描述 最长公共子序列(Longest Common Subseuence,LCS)问题:给定两个字符串,求 ...

最新文章

  1. c语言小学生算法,急求:C语言小学生算法练习软件实现的任务:面向小学生,随机选择两个整数进行加、减、乘、除,要求学生解答。设计内容:1、电...
  2. Android开发--Service和Activity通过广播传递消息
  3. jquery文件上传插件 uploadify java_jQuery文件上传插件Uploadify使用指南
  4. 练习1-17 编写一个程序,打印长度大于80个字符的所有输入行.
  5. socket技术难点
  6. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings
  7. Educational Codeforces Round 14 - F (codeforces 691F)
  8. JavaScript之array
  9. 为何要进行软件维护?维护的种类及目标?
  10. python可见图算法_基于自适应显着性的图像分割(源码开放)
  11. Delphi编译指令了解学习
  12. ei eo eq什么意思_音响中的EQ是什么意思呀?
  13. 《软技能:代码之外的生存指南》一一35.2 找出你的短板
  14. 网络蜘蛛Spider的逻辑Logic(一)
  15. 计算机数字模拟仿真软件,实时数字仿真系统
  16. VisualStudio2017密钥(key)
  17. 数据库事务特性学习笔记
  18. 普罗米修斯-Grafana 面板
  19. 为什么需要云计算机,为什么需要云计算?
  20. 域名dns劫持问题如何预防

热门文章

  1. 微信小程序之组件 —— 微信小程序教程系列(19)
  2. oracle查询练习2(解析+答案)
  3. 99的测试人还不会用nose进行自动化测试
  4. JAVA通过tcp通信劳易测BCL 308i扫码枪获取数据
  5. 用sort对vector排序(转载)
  6. 第一篇图像处理论文审稿意见修改说明
  7. system.data.oracleclient
  8. 如何加密/弄乱C源代码
  9. c++ bool类型
  10. 王阳明《心学》小总结