dp-最長公共子序列(LCS)
阿新 • • 發佈:2017-08-31
維數 追加 brush 解決 復雜 long long abcde urn 二維
字符序列 與 字符字串的區別
序列是可以不連續的字符串 , 字串必須要是連續的 。
問題描述 :
給定兩串字符串 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; }
dp-最長公共子序列(LCS)