最長公共子序列問題

最長公共子序列問題 (LCS,Longest Common Subsequence)

在這裏插入圖片描述
定義 d[i][j]:=s1sit1tjd[i][j]:=s_1…s_i和t_1…t_j 對應的LCS的長度

s1si+1t1tj+1∴ s_1…s_{i+1}和t_1…t_{j+1} 對應的公共子列可能是:

  1. si+1=tj+1s_{i+1}=t_{j+1} 時,在 s1sit1tjs_1…s_i和t_1…t_j 的公共子列末尾追加上 si+1s_{i+1}
  2. s1sit1tj+1s_1…s_{i}和t_1…t_{j+1} 的公共子列
  3. s1si+1t1tjs_1…s_{i+1}和t_1…t_{j} 的公共子列

由此得到遞推公式:
dp[i+1][j+1]={dp[i][j]+1si+1=tj+1max(dp[i][j+1],dp[i+1][j]) dp[i+1][j+1]=\left\{ \begin{array}{rcl} dp[i][j]+1&& s_{i+1}=t_{j+1}\\ \max (dp[i][j+1],dp[i+1][j])&& 其他 \end{array} \right.
時間複雜度爲O(nm)O(nm)dp[n][m]dp[n][m]就是LCS的長度

int n,m,dp[maxn+1][maxn+1];
char s[maxn],t[maxn];
void solve(){
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            if(s[i]==t[j]) dp[i+1][j+1]=dp[i][j]+1;
            else dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
        }
    cout<<dp[n][m];
}
發佈了120 篇原創文章 · 獲贊 63 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章