---
# System prepended metadata

title: 1143. Longest Common Subsequence
tags: [LCS, dp]

---

# 1143. Longest Common Subsequence
##### link: https://leetcode.com/problems/longest-common-subsequence/
###### tags: `dp` `LCS`
* 這是 DP 問題中經典的 " 子序列問題 "
* 我們需要製作一個二維 DP 表，如下圖:

>  ![](https://hackmd.io/_uploads/SyI7KjyL3.png)
>  
此 DP 表的定義是：**對於字串 $str1[0...i-1]$ 和 $str2[0...j-1]$，他們的 LCS 長度是 $dp[i][j]$** 

在更新 $dp$ 表時，要注意以下兩種情形：
1. $str1[i] == str2[j]$ ：$dp[i][j] = dp[i-1][j-1]+1$，因為是 $str1[i-1]$ 和 $str2[j-1]$ 所有的共同序列加上一個新來的 $str1[i]$ 字母。
2. $str1[i]$ != $str2[j]$：$dp[i][j] = max(dp[i-1][j], dp[i][j-1])$，因為 $str1[i]$ 和 $str2[j]$ 兩個字元至少有一個不在共同子序列中

* code：
```C++=
class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int m=text1.size(), n=text2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        for (int i=1;i<=m;i++){
            for (int j=1;j<=n;j++){
                if (text1[i-1] == text2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                }
                else if (text1[i-1] != text2[j-1]){
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        return dp[m][n];
    }
};
```
---
### 同場加映：d231. 97北縣賽-2-基因序列密碼問題
##### link: https://zerojudge.tw/ShowProblem?problemid=d231
* 概念一樣，只是這題要求印出共同子序列長什麼樣子。
```C++

#include <iostream>
#include <vector>

using namespace std;

string s1,s2;

int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    while (cin>>s1>>s2){
        vector<vector<string>> dp(s1.size()+1,vector<string>(s2.size()+1,""));
        for (int i=1;i<=s1.size();i++){
            for (int j=1;j<=s2.size();j++){
                if (s1[i-1] == s2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+ s1[i-1];
                }
                else if (s1[i-1] != s2[j-1]){
                    if (dp[i-1][j].size() > dp[i][j-1].size()) dp[i][j] = dp[i-1][j];
                    else dp[i][j] = dp[i][j-1];
                }
            }
        }
        if (dp[s1.size()][s2.size()] == "") cout<<"E"<<"\n";
        else cout<<dp[s1.size()][s2.size()]<<"\n";
        
    }

    return 0;
}
```

