• LCS最长公共子序列


    题目描述

    给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence)。比如字符串1:BDCABA;字符串2:ABCBDAB。则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA。序列无须是连续的,重复即可。

    解题思路

    • 暴力遍历
    • 动态规划

    暴力遍历

    字符串1:BDCABA
    字符串2:ABCDBAB
    自行匹配, 不看出有三种匹配最长公共子序列匹配结果:BDBA,BDAB,BCAB

    Dynamic Programing

    • m[i]=n[j]
      lcs[i][j]=lcs[i][j]+1

    • m[i]=n[j]
      lcs[i][j]=max{lcs[i][j-1],lcs[i-1][j]}
      代码部分实现:

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    int max(int a, int b) 
    {
    	return (a>b)? a:b;
    }
    
    /**
     * 返回X[0...m-1]和Y[0...n-1]的LCS的长度 
     */
    int lcs(string &X, string &Y, int m, int n)
    {
    	// 动态规划表,大小(m+1)*(n+1)
    	vector<vector<int>> table(m+1,vector<int>(n+1));  
    
    	for(int i=0; i<m+1; ++i)
    	{
    		for(int j=0; j<n+1; ++j)
    		{
    			// 第一行和第一列置0
    			if (i == 0 || j == 0)
    				table[i][j] = 0;
    
    			else if(X[i-1] == Y[j-1])
    				table[i][j] = table[i-1][j-1] + 1;
    		 
    			else
    				table[i][j] = max(table[i-1][j], table[i][j-1]);
    		}
    	}
    
    	return table[m][n];
    }
    
    int main()
    {
    	string X = "ABCBDAB";
    	string Y = "BDCABA";
    
    	cout << "The length of LCS is " << lcs(X, Y, X.length(), Y.length());
    	cout << endl;
    	 
    	getchar();
    	return 0;
    }
    
  • 相关阅读:
    浅谈 LCA
    树剖毒瘤题整理
    树链剖分&咕咕咕了好久好久的qtree3
    洛谷P4095新背包问题
    洛谷P4127同类分布
    洛谷P4124 手机号码
    数位dp好题整理+自己wa过的细节记录
    P4999烦(gui)人(chu)的数学作业
    洛谷P4317 花(fa)神的数论题(数位dp解法)
    网络流之最短路径覆盖问题
  • 原文地址:https://www.cnblogs.com/yvzhu/p/13955981.html
Copyright © 2020-2023  润新知