动态规划二:最长公共子序列(LCS)

  1.两个子序列:X={x1,x2....xm},Y={y1,y2....yn},设Z={z1,z2...zk}。

  2.最优子结构:

  1)如果xm=y,则zk=xm=yn且Zk-1是Xm-1和Yn-1的一个LCS。

  2)如果xm!=y,则zk!=xm包含Z是Xm-1和Y的一个LCS。

  3)如果xm!=y,则zk!=yn包含Z是X和Yn-1的一个LCS。

  3.则由最优子结构可得递归式:

  

  4.实现:

 1 #include<string>
 2 #include<iostream>
 3 using namespace std;
 4
 5 int arr[20][20] = {};
 6 void LCS(string str1, string str2){
 7     int len1 = str1.length();
 8     int len2 = str2.length();
 9     //边界
10     for (int i = 0; i <= len1; i++)
11         arr[i][0] = 0;
12     for (int j = 0; j <= len2; j++)
13         arr[0][j] = 0;
14     //检验
15     for (int i = 1; i <= len1; i++)
16     {
17         for (int j = 1; j <= len2; j++)
18         {
19             if (str1[i - 1] == str2[j - 1]) //记录
20             {
21                 arr[i][j] = arr[i - 1][j - 1] + 1;
22             }
23             else if (arr[i][j - 1] >= arr[i - 1][j])
24             {
25                 arr[i][j] = arr[i][j - 1];
26             }
27             else
28             {
29                 arr[i][j] = arr[i - 1][j];
30             }
31         }
32     }
33 }
34
35 void printLCS(string str1, string str2,int len1, int len2){
36     cout << "最长公共子序列长为:" << arr[len1][len2] << endl;
37     //倒序输出
38     while (len1&&len2){
39         if (str1[len1-1]==str2[len2-1])
40         {
41             cout << str1[len1 - 1];
42             len1--;
43             len2--;
44         }
45         else if (arr[len1][len2-1]>=arr[len1-1][len2])
46         {
47             len2--;
48         }
49         else{
50             len1--;
51         }
52     }
53     cout << endl;
54 }
55
56 int main()
57 {
58     string str1 = "abcdsnnnn";
59     string str2 = "acbdanm";
60     LCS(str1, str2);
61     printLCS(str1, str2,str1.length(), str2.length());
62     return 0;
63 }
时间: 2024-10-29 12:52:52

动态规划二:最长公共子序列(LCS)的相关文章

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

tips : 本文内容是参考了很多著名博客和自己的思考得出的,如有不当欢迎拍砖. 先简单说一下动态规划 通俗地说:动态规划就是将一个可以划分为子问题的问题进行递归求解,不过动态规划将大量的中间结果保存起来, 不管它们是否会用得到,从而在后面的递归求解过程中可以快速求解.由此可以看得出来动态规划是一个以牺牲空间 为代价换取时间的算法. 对于最长公共子序列的题目不用多说,现在来分析一下LCS的动态规划解决思路: 一.首先先观察问题是否符合动态规划最明显的两个特征:最优子结构和重叠子问题 方便起见,以

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

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们

动态规划-最长公共子序列LCS

0 问题 给定两个字符串,求最长公共子序列LCS. 也就是说两个字符串中都有的部分,或者理解为,两个字符串同时都删除字符串中的某些字符,使得最终的两个字符串,相等,且是最长的. 1 分析 假设两个str1,str2字符串,已经知道了最长公共子序列长度为L 那么,当在str1和str2,两个的尾部,同时添加一个相同的字符,比如a,那么新的str1,和str2的最长公共子序列长度就是L+1 当str1后面添加一个字符,str2不添加,那么最长公共子序列长度为L 反之,str1不添加,str2添加,那

动态规划解决最长公共子序列问题(转)

原文链接 动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加. 解决思想: 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法. [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后

动态规划解最长公共子序列问题(转)

 动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加. 为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法. [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列

【算法导论之七】动态规划求解最长公共子序列

一.动态规划的概念 动态规划(Dynamic Programming)是通过组合子问题的解而解决整个问题的.分治算法是指将问题划分成一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原始问题的解,与此不同,动态规划适用于子问题不是独立的情况,也就是各个子问题包含公共的子问题.在这种情况下,采用分治法会做许多不必要的工作,即重复地求解公共地子问题.动态规划算法对每个子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题时重新计算答案. 动态规划通常应用于最优化问题.此类问

算法——动态规划篇——最长公共子序列

问题描述      最长公共子序列,英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列.       解决最长公共子序列,一种常用的办法,就是穷举法,组合出所有的情况,但是这样对于长序列的情况来说,是非常不实际.. 假设现在有两个序列,x[]={'A','B','C','B','D','A','B'};y[]={'B','D','C','A'

[2016-05-09][51nod][1006 最长公共子序列Lcs]

时间:2016-05-09 21:12:54 星期一 题目编号:[2016-05-09][51nod][1006 最长公共子序列Lcs] 题目大意:[2016-05-09][51nod][1006 最长公共子序列Lcs].md 分析:动态规划 dp[i][j] 表示字符串A以第i个位置 ,字符串B以第j个位置的最长公共子序列的长度 dp[i][j] = dp[i - 1][j - 1] + 1 if a[i] == a[j] else dp[i][j] == max(dp[i - 1][j] ,

序列最的问题之最长公共子序列LCS

在程序设计竞赛中,我们时常会遇到序列求最值的问题.在讲今天的问题之前,先小小的说明一下,子序列与子串的问题. 子序列:在原序列中不一定连续: 子串:在原序列中必须连续. 接下来,就开始今天要讲的最长公共子序列LCS(Longest Common Subsequence).对于LCS这一类的问题,一般是相对于两个序列而言,str[]与ch[].先假设str的长度为n,ch的长度为m.假设str[]="ASBDAH",ch[]="SDAAH";其中"SDA&q

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

我们之前提到过过动态规划的几个经典问题: 动态规划原理:http://blog.csdn.net/ii1245712564/article/details/45040037 钢条切割问题:http://blog.csdn.net/ii1245712564/article/details/44464689 矩阵链乘法问题:http://blog.csdn.net/ii1245712564/article/details/44464689 今天我们来看一下动态规划的另外一个经典问题:最长公共子序列(