动态规划,求最长公共子序列

引进一个二维数组Array[][],用Array[i][j]记录A[i]与B[j] 的LCS 的长度,sign[i][j]记录ARRAY[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。

问题的递归式写成:

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

// LCSLength.cpp : Defines the entry point for the console application.
//
#include "StdAfx.h"

#include "iostream"
#include "string"
#include "vector"
using namespace std;

vector< vector<int> > sign;
vector< vector<int> > array ;
string A;
string B;
void printsign(vector< vector<int> > & sign);
int getLCSlength(string strA,string strB){
    int leni = strA.length() + 1;
    int lenj = strB.length() + 1;
    int i = 0;
    int j = 0;
    // init the array

    array.resize(leni);
    for(i = 0;i<leni;i++)
        array[i].resize(lenj);
    // init the sign
    sign.resize(leni);
    for(i = 0;i<leni;i++)
        sign[i].resize(lenj);

    for(i = 1;i<leni;i++)
        for(j = 1;j<lenj;j++){
            if(strA[i-1] == strB[j-1]){          //dp[i][j] = dp[i-1][j-1] + 1  如果X[i-1] = Y[i-1]
                array[i][j] = array[i-1][j-1] + 1;
                sign[i][j] = 1;      //"\"
            }
            else
                if(array[i-1][j]>=array[i][j-1]){  //下面两种情况,p[i][j] = max{ dp[i-1][j], dp[i][j-1] }  如果X[i-1] != Y[i-1]
                    array[i][j] = array[i-1][j];
                    sign[i][j] = 2;  //"^"
                }
                else{
                    array[i][j] = array[i][j-1];
                    sign[i][j] = 0;  //"<-"
                }
        }

        return array[leni-1][lenj-1];
}

void printsign(vector< vector<int> > & sign){
    cout<<"~~~~~~~~~~~~~~~~~~~~"<<endl;
    vector< vector<int> >::iterator iti = sign.begin();
    for(;iti!=sign.end();iti++){
        vector<int>::iterator itj = (*iti).begin();
        for(;itj != (*iti).end();itj++){
            cout<<*itj<<" ";
        }
        cout<<endl;
    }

}
void printLCS(int i,int j){

    if( i == 0 || j == 0)
        return ;
    if(sign[i][j] == 1){
        printLCS(i-1,j-1);
    //    cout<<"i = "<<i<<" j = "<<j<<" ";
        cout<<A[i-1];
    }
    if(sign[i][j] == 2){
        printLCS(i-1,j);
    }
    if(sign[i][j] == 0){
        printLCS(i,j-1);
    }
}
int main(int argc, char const *argv[])
{
    A = "ABCBDAB";
    B = "BDCABA";

    cout<<"the LCS length is "<<getLCSlength(A,B)<<endl;

    printsign(array);
    printsign(sign);
    printLCS(A.length(),B.length());
    cout<<endl;
    return 0;
}
时间: 2024-10-05 09:49:27

动态规划,求最长公共子序列的相关文章

动态规划求最长公共子序列问题

#include<iostream> #include<string> #include<vector> using namespace std; //找两个子串str1,str2的最长公共子串substr void findLongestSubString(string &str1, string &str2, string &substr){ if (str1.empty() || str2.empty()){ return; } //定义二

HDU 1243 反恐训练营 (动态规划求最长公共子序列)

反恐训练营 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3040    Accepted Submission(s): 693 Problem Description 当今国际反恐形势很严峻,特别是美国"9.11事件"以后,国际恐怖势力更是有恃无恐,制造了多起骇人听闻的恐怖事件.基于此,各国都十分担心恐怖势力会对本国社会造

九度OJ 1042 Coincidence (动态规划求最长公共子序列)

题目1042:Coincidence 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1689 解决:898 题目描述: Find a longest common subsequence of two strings. 输入: First and second line of each input case contain two strings of lowercase character a-z. There are no spaces before, inside or aft

hdoj-1159-Common Subsequence【动态规划求最长公共子序列】

Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 28152 Accepted Submission(s): 12556 Problem Description A subsequence of a given sequence is the given sequence with some element

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

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

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

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

(hdu step 3.2.2)Common Subsequence(简单dp:求最长公共子序列的长度)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 976 Accepted Submission(s): 538   Probl

算法导论_动态规划_最长公共子序列

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

[algorithm]求最长公共子序列问题

最直白方法:时间复杂度是O(n3), 空间复杂度是常数 reference:http://blog.csdn.net/monkeyandy/article/details/7957263 /** ** [email protected] ** http://blog.csdn.net/MonkeyAndy **/ 首先介绍动态规划方法的相关知识 动态规划方法的基本思想: 分成若干个子问题,先求解子问题,然后根据子问题的解求得原问题的解.经分解得到的子问题往往不是互相独立的.可重复利用! 其核心思

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

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