文章目录

  • 一、动态规划概念
    • 1. 动态规划步骤
  • 最长公共子序列问题
    • 题目
    • 示例
    • 分析
    • 代码(递归)
    • 查表
    • 打印最长公共子序列

一、动态规划概念

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的。若用分治法解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间。

然而,不同子问题的数目常常只有多项式量级。在用分治法求解时,有些子问题被重复计算了许多次。如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。为了达到这个目的,可以用一个表来记录所有已解决的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填人表中。这就是动态规划法的基本思想。具体的动态规划算法是多种多样的,但它们具有相同的填表格式。

1. 动态规划步骤

(1) 找出最优解的性质,并刻画其结构特征;
(2)递归地定义最优值;
(3)以自底向上的方式计算出最优值;
(4)根据计算最优值时得到的信息,构造最优解。

最长公共子序列问题

题目

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例

示例1:

输入:text1 = "abcde", text2 = "ace"
输出:3
解释:最长公共子序列是 "ace" ,它的长度为 3 。

示例2:

输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc" ,它的长度为 3 。

示例3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0 。

分析

设两个序列为
X = { x1, x2, x3, …, xm - 1, xm} ,元素个数为m个。
Y = { y1, y2, y3, …, yn - 1, yn},元素个数为n个。

设公共子序列为:
Z = { z1, z2, z3, …, zk - 1, zk }, 元素个数为k个。

情况分析:

  1. 如果 xm == yn,则 zk = xm = yn,最后一个元素相等,那也就意味着我们可以把问题规模缩小,使得:
zk - 1 = xm - 1 && yn - 1

原规模的最长公共子序列长度就是 Z(k - 1) + 1

  1. 如果 xm != yn, xm != zk;那么
zk = xm - 1 && yn
  1. 如果yn != xm, yn != zk, 那么
zk = xm && yn - 1

令 c [m][n]为最长公共子序列,m为序列X的元素个数,n为Y序列的元素个数, 那么会得到以下情况:

  1. 当m或n为0时,最长公共子序列为0。
c[m][n] = (m == 0 || n == 0) ? 0;
  1. 当m > 1, n > 1, xm == yn时
c[m][n] = (xm == yn) ? c[m - 1][n - 1] + 1;
  1. 当 m > 1, n > 1, xm != yn时
c[m][n] = (xm != yn) ? max(c[m - 1][n], c[m][n - 1]);

代码(递归)

int LCSLength(char* X, char* Y, int m, int n)
{if (m == 0 || n == 0) return 0;else{if (X[m] == Y[n])return LCSLength(X, Y, m - 1, n - 1) + 1;else{int max1 = LCSLength(X, Y, m - 1, n);int max2 = LCSLength(X, Y, m, n - 1);return max1 > max2 ? max1 : max2;}}
}int main(void)
{char X[] = { "ABCBDAB" };char Y[] = { "BDCABA" };int xm = strlen(X), yn = strlen(Y);int maxlen = LCSLength(X, Y, xm, yn);cout << maxlen << endl;return 0;
}

运行结果:

查表

#include<iomanip>template<typename T>
void Print_vec(vector<vector<T> >& c)
{int m = c.size();for (int i = 0; i < m; ++i){int n = c[i].size();for (int j = 0; j < n; ++j){cout << setw(3) << c[i][j];}cout << endl;}cout << endl;
}int LCSLength(char* X, char* Y, int m, int n, vector<vector<int> >& c, vector<vector<int> >& s)
{if (m == 0 || n == 0) return 0;else if (c[m][n] != 0) return c[m][n];else{ if (X[m] == Y[n]){c[m][n] = LCSLength(X, Y, m - 1, n - 1, c, s) + 1;s[m][n] = 1;}else{int max1 = LCSLength(X, Y, m - 1, n, c, s);int max2 = LCSLength(X, Y, m, n - 1, c, s);if (max1 > max2){c[m][n] = max1;s[m][n] = 2;}else{c[m][n] = max2;s[m][n] = 3;}}}return c[m][n];
}int main(void)
{char X[] = { "#ABCBDAB" };char Y[] = { "#BDCABA" };int xm = strlen(X) - 1, yn = strlen(Y) - 1;vector<vector<int> > c, s;c.resize(xm + 1);s.resize(xm + 1);for (int i = 0; i < xm + 1; ++i){c[i].resize(yn + 1);s[i].resize(yn + 1);}int maxlen = LCSLength(X, Y, xm, yn, c, s);Print_vec(c);Print_vec(s);cout << maxlen << endl;return 0;
}


这样可得出最长公共子序列是哪些字符。

打印最长公共子序列

void LCS(char* X, vector<vector<int> >& s, int i, int j)
{if (i == 0 || j == 0) return;if (s[i][j] == 1){LCS(X, s, i - 1, j - 1);cout << X[i];}else if (s[i][j] == 2){LCS(X, s, i - 1, j);}else{LCS(X, s, i, j - 1);}
}int main(void)
{char X[] = { "#ABCBDAB" };char Y[] = { "#BDCABA" };int xm = strlen(X) - 1, yn = strlen(Y) - 1;vector<vector<int> > c, s;c.resize(xm + 1);s.resize(xm + 1);for (int i = 0; i < xm + 1; ++i){c[i].resize(yn + 1);s[i].resize(yn + 1);}int maxlen = LCSLength(X, Y, xm, yn, c, s);Print_vec(c);Print_vec(s);cout << maxlen << endl;LCS(X, s, xm, yn);return 0;
}

运行结果:

算法:动态规划——最长公共子序列相关推荐

  1. 用动态规划算法实现最长公共子序列问题的算法(java实现)

    用动态规划算法实现最长公共子序列问题的算法 public class longestCommonSubsequence {//构造追踪数组rec,记录子问题来源private static Strin ...

  2. LCS算法:最长公共子序列

    LCS算法:最长公共子序列定义: 一个序列A任意删除若干个字符得到新序列B,则A叫做B的子序列 两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列 例如: X={A,B,C,B ...

  3. 最长公共子序列动态规划c语言,动态规划----最长公共子序列(C++实现)

    最长公共子序列 题目描述:给定两个字符串s1 s2 - sn和t1 t2 - tm .求出这两个字符串的最长公共子序列的长度.字符串s1 s2 - sn的子序列指可以表示为 - { i1 < i ...

  4. 动态规划—最长公共子序列问题 HDU-1159 Common Subsequence

    动态规划-最长公共子序列问题 Common Subsequence [ HDU - 1159 ] A subsequence of a given sequence is the given sequ ...

  5. 详解动态规划最长公共子序列--JavaScript实现

    前面两篇我们讲解了01背包问题和最少硬币找零问题.这篇将介绍另一个经典的动态规划问题--最长公共子序列.如果没看过前两篇,可点击下面链接. 详解动态规划最少硬币找零问题--JavaScript实现 详 ...

  6. 动态规划1--最长公共子序列

    动态规划1--最长公共子序列 一.动态规划 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并 综合子问题的解导出大问题的解的方法,问题求解耗时 ...

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

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

  8. java lcs_Java算法之最长公共子序列问题(LCS)实例分析

    本文实例讲述了Java算法之最长公共子序列问题(LCS).分享给大家供大家参考,具体如下: 问题描述:一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X= { x1, x ...

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

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

  10. 算法导论之动态规划(最长公共子序列和最优二叉查找树)

    动态规划师通过组合子问题的解而解决整个问题,将问题划分成子问题,递归地求解各子问题,然后合并子问题的解而得到原问题的解.和分治算法思想一致,不同的是分治算法适合独立的子问题,而对于非独立的子问题,即各 ...

最新文章

  1. 卷积神经网络中十大拍案叫绝的操作!
  2. python使用imbalanced-learn的ClusterCentroids方法进行下采样处理数据不平衡问题
  3. opencv-python 视频处理之时光倒流
  4. 2021年中国少儿编程行业报告
  5. java 类变量方法实例对象方法
  6. 1.1.2获取和控制线程状态(Getting and Seeting Thread State)
  7. 【转】Laplace 算子
  8. 如何将PDF文件格式转换为Word文档最新教程分享
  9. Python输入一个三位数,输出其个位数字、十位数字和百位数字。
  10. Java时间系列(JDK8)--Duration的使用
  11. 索尼爱立信滑盖机java_可爱Walkman滑盖机 索尼爱立信W100i评测
  12. 2021_SIGIR_ConsisRec: Enhancing GNN for Social Recommendation via Consistent Neighbor Aggregation
  13. 如何理解实时频谱分析仪的几个“带宽”参数(1)——实时带宽(RTBW)
  14. linux中cpu_to_be32,Linux cpufreq framework(2)
  15. EKL日志平台架构概括
  16. c语言灵异事件之“字符串被吞”
  17. python语言变量名规则_python语言变量命名规则
  18. [ 数通面试 ] 奇安信技术支持工程师 面试分享
  19. c语言程序设计竞赛策划书,C语言程序设计策划书
  20. 湍流参数计算c语言,常用的湍流模型

热门文章

  1. 我为自己扭扭捏捏的性格感到羞耻
  2. OSPF 网络类型和LSA限制
  3. linux软件卸载及清理
  4. 携程酒店评论爬虫心得
  5. Service层控制事务
  6. Promise的用法及如何解决回调地狱
  7. Java面试中常见的高并发解决方案
  8. 分布式秒杀实战之订单数据分表
  9. 2015新年春节素材图片
  10. SPI协议详解(总结)