dp-最长公共子序列(LCS)

字符序列 与 字符字串的区别

  序列是可以不连续的字符串 , 字串必须要是连续的 。

问题描述 :

  给定两串字符串 abcde 和 acdf , 找出 2 串中相同的字符序列,观察知 相同的字符序列为 acd 。

方法一 : 暴力解决

  对于一个长度为 n 的串 , 它的字串总共有 2^n 个,在用着 2^n 个字串与另一个长度为 m 的串一一比较 ,那么复杂度为 m * 2^n 。复杂度是指数级别的,显然会超时。

方法二 : 动态规划求解

  两个串长度为 n 和 m , 建一个二维数组 , 用来记录状态 ,并且初始化数组内容为 0 ,m 和 n 分别从 0 开始 , m++ , n++ 循环

  产生公共子序列的可能情况 :

  两个序列 s1~sn 和 t1 ~ tm , 当 s i+1 == t i+1 时 , 在s1 ~ si 和 t1 ~ ti 的公共子序列末尾追加 s i+1 。

  s1~si 和 t1~ti+1的公共序列。

  s1~si+1 和 t1 ~ ti 的公共序列 。

代码示例 :

  

/*
 * Author:  renyi
 * Created Time:  2017/8/31 8:33:36
 * File Name: 1.cpp
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
const int maxint = -1u>>1;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define ll long long

int dp[10][10];

int main() {
    char a[] = "abcdegghh";
    char b[] = "cdefgh";

    int len1 = strlen(a);
    int len2 = strlen(b);

    for(int i = len1; i > 0; i--){
        a[i] = a[i-1];
    }
    for (int i = len2; i > 0; i--){
        b[i] = b[i-1];
    }

    for(int i = 1; i <= len1; i++){
        for(int j = 1; j <= len2; j++){
            if (a[i] == b[j]){
                dp[i][j] = dp[i-1][j-1]+1;
            }
            else dp[i][j] = Max(dp[i-1][j], dp[i][j-1]);
        }
    }
   // printf("%d\n", dp[len1][len2]); // 公共字串的长度

 /*   for (int i = len1, j = len2; i > 0 && j > 0; ){ // 输出公共字串
        if (a[i] == b[j]) {
            printf("%c\t", a[i]);
            i-- , j--;
        }
        else if(dp[i][j-1] >= dp[i-1][j]) j--;
        else i--;
    }

*/  int i = len1 , j = len2;
    while (i && j) {
        if ( a[i] == b[j]){
            printf("%c\t" , a[i]);
            i-- , j--;
        }
        else if (dp[i][j-1] >= dp[i-1][j]) j--;
        else i--;
    }
    return 0;
}

      

时间: 2024-08-06 03:23:24

dp-最长公共子序列(LCS)的相关文章

51nod 1006 最长公共子序列Lcs(dp+string,无标记数组实现)

1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 取消关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) Output 输出最长的子序列,如果有多个,随意输出1个. Input示

[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] ,

POJ 2250 Compromise (DP,最长公共子序列)

Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6440 Accepted: 2882 Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria must be fulfille

1006 最长公共子序列Lcs

1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) Output 输出最长的子序列,如果有多个,随意输出1个. Input示例 abcicba abdkscab Outpu

POJ 1458 Common Subsequence(最长公共子序列LCS)

POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列长度. 分析: 本题不用输出子序列,非常easy,直接处理就可以. 首先令dp[i][j]==x表示A串的前i个字符和B串的前j个字符的最长公共子序列长度为x. 初始化: dp全为0. 状态转移: IfA[i]==B[j] then dp[i][j]= dp[i-1][j-1]+1 else dp[

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

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

求三个字符串的最长公共子序列LCS(A,B,C)

LCS(A,B,C)!=LCS(A,LCS(B,C)) 反例: abcd abcde abced LCS(B,C)求出来可能是abce或者abcd dp[i][j][k]表示A[0...i],B[0...j],C[0...k]的LCS 转移方程: if (a[i]==b[j]&&b[j]==c[k]) dp[i][j][k]=dp[i-1][j-1][k-1]+1; else dp[i][j][k]=max(max(dp[i][j][k], dp[i-1][j][k]), max(dp[i

编程算法 - 最长公共子序列(LCS) 代码(C)

最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符串的子序列并一定要连续, 能够包含间隔. 即最长公共子序列问题(LCS, Longest Common Subsequence) 使用动态规划, 假设字符相等, 两个字符串就依次递增一位, 一直到字符串的结尾. 代码: /* * main.cpp * * Created on: 2014.7.17

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

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

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

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