LCS算法妙解html
LCS问题简述:最长公共子序列算法
一个数列 S,若是分别是两个或多个已知数列的子序列,且是全部符合此条件序列中最长的,则S 称为已知序列的最长公共子序列。数组
LCS问题的分支:最长公共子串与最长公共子序列ide
子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而得到的新序列;更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则没必要。好比字符串acdfg同akdfc的最长公共子串为df,而他们的最长公共子序列是adf。idea
LCS解题策略:spa
one:穷举法。。。复杂度再也不多说,想一想2的N次方就感到可怕;code
two:矩阵,也就是动态规划节LCS问题,也就是今天咱的标题;htm
下面来细讲the twith idea:blog
由此图能够看出此经典算法的思路;排序
下面是代码,方便你们理解:
1 #include<stdio.h> 2 #include<string.h> 3 #define MAX(a,b) (a>b?a:b) 4 const int MAXN=1010; 5 int dp[MAXN][MAXN]; 6 char a[MAXN],b[MAXN]; 7 int main(){ 8 while(~scanf("%s%s",a+1,b+1)){ 9 memset(dp,0,sizeof(dp)); 10 int i,j; 11 for( i=1;a[i];i++){ 12 for(j=1;b[j];j++){ 13 if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1; 14 else dp[i][j]=MAX(dp[i][j-1],dp[i-1][j]); 15 } 16 } 17 printf("%d\n",dp[i-1][j-1]); 18 } 19 return 0;}
此递归关系为:
此算法时间复杂度为n*m,空间复杂度也是n*m;
另外若要记录路径就比较复杂了;
lcs解决lis问题:
须要先排序,而后与原数组求最长公共子序列;
下面是道题poj上的,就用到了此题的思想:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 43194 | Accepted: 17514 |
Description
Input
Output
Sample Input
abcfbc abfcab programming contest abcd mnp
Sample Output
4 2 0
还有南阳oj上面有道最长公共子序列更是LCS的模板;