在程序設計競賽中,咱們時常會遇到序列求最值的問題。在講今天的問題以前,先小小的說明一下,子序列與子串的問題。ios
子序列:在原序列中不必定連續;數組
子串:在原序列中必須連續。ide
接下來,就開始今天要講的最長公共子序列LCS(Longest Common Subsequence).對於LCS這一類的問題,通常是相對於兩個序列而言,str[]與ch[]。先假設str的長度爲n,ch的長度爲m。假設str[]="ASBDAH",ch[]="SDAAH";其中"SDA"是其中的str與ch的一個子序列,但不是最長的。最長的子序列爲"SDAH",固然,有時候咱們會看到兩個串中有多個相同長度的子序列,這不足爲奇。spa
若是咱們枚舉str的子序列,那麼將有2n個子序列,這很不切實際。所以咱們能夠試着讓str中前1,2,3……n參與的狀況下分別與ch串中前1,2……m參與狀況求出LCS。設計
dp[i][j]表示str前i個參與,以及ch前j個參與的LCS。code
當str[i] == ch[j]時,只須要記錄統計出str[1~i - 1],ch[1~j - 1]的LCS,在此基礎上加1.blog
當str[i] != ch[j]時,咱們只須要求str[1 ~ i - 1]且ch[1~j],str[1 ~ i]且ch[1~j-1]的最大值便可。get
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <math.h> 5 using namespace std; 6 const int MAX = 100 + 10; 7 char str[MAX], ch[MAX]; 8 int dp[MAX][MAX]; 9 10 int max(int a, int b){ return a > b ? a : b;} 11 12 int main() 13 { 14 int t, n, m; 15 scanf("%d", &t); 16 getchar(); 17 18 while (t--) 19 { 20 scanf("%s%s", str, ch); 21 n = strlen(str); 22 m = strlen(ch); 23 24 for (int i = 0; i < n; i++) 25 { 26 for (int j = 0; j < m; j++) 27 { 28 if (str[i] == ch[j]) 29 { 30 dp[i + 1][j + 1] = dp[i][j] + 1; 31 } 32 else dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]); 33 } 34 } 35 36 printf("%d\n", dp[n][m]); 37 38 } 39 40 return 0; 41 }