动态规划

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

为了节约反复求同样子问题的时间,引入一个数组。无论它们是否对终于解实用。把全部子问题的解存于该数组中,这就是动态规划法所採用的基本方法。

【问题】 求两字符序列的最长公共字符子序列

问题描写叙述:字符序列的子序列是指从给定字符序列中任意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。

令给定的字符序列X=“x0,x1,…。xm-1”,序列Y=“y0,y1。…。yk-1”是X的子序列。存在X的一个严格递增下标序列<i0,i1,…。ik-1>,使得对全部的j=0,1,…,k-1,有xij=yj。

比如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。

考虑最长公共子序列问题怎样分解成子问题,设A=“a0。a1。…,am-1”,B=“b0,b1,…。bm-1”,并Z=“z0。z1,…,zk-1”为它们的最长公共子序列。不难证明有下面性质:

(1) 假设am-1=bn-1,则zk-1=am-1=bn-1,且“z0。z1,…。zk-2”是“a0,a1。…,am-2”和“b0,b1。…,bn-2”的一个最长公共子序列;

(2) 假设am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0。z1,…。zk-1”是“a0。a1,…。am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;

(3) 假设am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1。…,zk-1”是“a0。a1,…,am-1”和“b0。b1。…,bn-2”的一个最长公共子序列。

这样,在找A和B的公共子序列时,如有am-1=bn-1。则进一步解决一个子问题,找“a0,a1。…,am-2”和“b0。b1,…,bm-2”的一个最长公共子序列。假设am-1!=bn-1,则要解决两个子问题,找出“a0。a1。…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1。…。bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。

求解:

引进一个二维数组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]。

问题的递归式写成:

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

算法分析:
因为每次调用至少向上或向左(或向上向左同一时候)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时開始返回。

返回时与递归调用时方向相反,步数同样,故算法时间复杂度为Θ(m + n)。

代码:

 #include <stdio.h>
#include <string.h>
#define MAXLEN 100void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN]){int i, j;for(i = 0; i <= m; i++)c[i][0] = 0;for(j = 1; j <= n; j++)c[0][j] = 0;for(i = 1; i<= m; i++){for(j = 1; j <= n; j++){if(x[i-1] == y[j-1]){c[i][j] = c[i-1][j-1] + 1;b[i][j] = 0;}else if(c[i-1][j] >= c[i][j-1]){c[i][j] = c[i-1][j];b[i][j] = 1;}else{c[i][j] = c[i][j-1];b[i][j] = -1;}}}
}void PrintLCS(int b[][MAXLEN], char *x, int i, int j)
{if(i == 0 || j == 0)return;if(b[i][j] == 0){PrintLCS(b, x, i-1, j-1);printf("%c ", x[i-1]);}else if(b[i][j] == 1)PrintLCS(b, x, i-1, j);elsePrintLCS(b, x, i, j-1);
}int main(int argc, char **argv)
{char x[MAXLEN] = ...{"ABCBDAB"};char y[MAXLEN] = ...{"BDCABA"};int b[MAXLEN][MAXLEN];int c[MAXLEN][MAXLEN];int m, n;m = strlen(x);n = strlen(y);LCSLength(x, y, m, n, c, b);PrintLCS(b, x, m, n);return 0;
}

认为思路很清晰,所以转载。

感谢作者:http://blog.csdn.net/yysdsyl/article/details/4226630

版权声明:欢迎follow我的开源项目:https://github.com/skyqinsc

动态规划解决方案最长公共子序列问题(开启)相关推荐

  1. 动态规划解决最长公共子序列

    动态规划解决最长公共子序列 问题描述 给定两个序列,例如 X = "ABCBDAB".Y = "BDCABA",求它们的最长公共子序列的长度. 递归关系 c[i ...

  2. 动态规划解最长公共子序列(LCS)(附详细填表过程)

    目录 相关概念 子序列形式化定义: 公共子序列定义: 最长公共子序列(以下简称LCS): 方法 蛮力法求解最长公共子序列: 动态规划求解最长公共子序列: 分析规律: 做法: 伪代码: 下面演示下c数组 ...

  3. javascript写算法(一) 动态规划:最长公共子序列

    csdn是疯了吗,右下角的广告是一个人站在猪屁股后面打它...看了一下居然是baidu算出来的广告嵌在了iframe里,fixed to viewport,真是够了.最近还频频出现的广告是一个光头男子 ...

  4. 动态规划之----最长公共子序列

    动态规划算法的基本要素: 1)最优子结构 当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质.问题的最优子结构性质提供了该问题可用动态规划算法求解的最重要线索. 在动态规划算法中,利用 ...

  5. 【动态规划】最长公共子序列与最长公共子串

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  6. 两个字符串的最长公共子序列长度_【面试】动态规划-之最长公共子序列、最长公共子串问题...

    先来说明下什么是最长公共子序列,什么是是最长公共子串,举一个实际例子,myblogs与belong,最长公共子序列为blog(myblogs, belong),最长公共子串为lo(myblogs, b ...

  7. 实验二 动态规划算法 最长公共子序列问题

    基本题一:最长公共子序列问题 一.实验目的与要求 1.熟悉最长公共子序列问题的算法: 2.初步掌握动态规划算法: 二.实验题 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,z ...

  8. 用动态规划解决最长公共子序列

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

  9. 【编程题 动态规划】最长公共子序列(详细注释 易懂)

    题目描述: 题目链接:最长公共子序列__牛客网 来源:牛客网 我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列.子串中的字符不一定在原字符串中连续. 例如字符串&q ...

最新文章

  1. 后端:SpringBoot集成Swagger-Bootstrap-UI,界面美观!
  2. win10 VScode配置GCC(MinGW)
  3. ConfigurationManager.AppSettings[] ConfigurationManager智能显示不出来
  4. 音乐编辑 java_求助 关于java编辑音乐
  5. localhost方式提交作业到spark运行
  6. mysql 创建函数_MySQL函数,存储过程,用户管理
  7. 大咖来信 | 轮值董事长徐直军,复盘华为AI战略出台始末
  8. python之路--小数据池,再谈编码,is和 == 的区别
  9. linux redis客户端怎么使用,linux 下安装redis并用QT写客户端程序进行连接
  10. python中的遍历range_python中for用来遍历range函数的方法
  11. 【带钢厚度预测】基于matlab GUI SVM带钢厚度预测【含Matlab源码 173期】
  12. 单体架构和微服务架构
  13. 计算机图形学实验——二维卡通人物交互
  14. Docker MSSQL 添加读取 MDF 文件
  15. 典型相关分析(Canonical Correlation Analysis, CCA)
  16. 微信小程序,引入WeUI组件库 扩展组件库
  17. mysql中常用的三种插入数据的语句
  18. Win10怎么通过ip添加网络打印机?
  19. FRDM-KW41Z开发板使用显示驱动芯片HD44780的方法
  20. Arduino中使用超声波测距实验

热门文章

  1. java 事件驱动模式_事件驱动
  2. mysql导入数据权限_mysql5.7导入数据的权限问题
  3. php无法加载dll插件,php无法加载动态库怎么办
  4. PaddlePaddle 中的若干基础命令中的问题
  5. 硕士论文评审记录2021年春季
  6. 三关节机械臂控制命令修改
  7. 如何让自学更有效率?
  8. 智能车竞赛车模轮子与电机齿轮的参数
  9. php进攻教程,如何对PHP程序中的常见漏洞进行攻击(下)_php基
  10. java 9宫格抽奖_前端js实现九宫格模式抽奖(多宫格抽奖)