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的模板;