最長公共子序列問題 (LCS,Longest Common Subsequence)
定義 d[i][j]:=s1…si和t1…tj 對應的LCS的長度
∴s1…si+1和t1…tj+1 對應的公共子列可能是:
- 當 si+1=tj+1 時,在 s1…si和t1…tj 的公共子列末尾追加上 si+1
- s1…si和t1…tj+1 的公共子列
- s1…si+1和t1…tj 的公共子列
由此得到遞推公式:
dp[i+1][j+1]={dp[i][j]+1max(dp[i][j+1],dp[i+1][j])si+1=tj+1其他
時間複雜度爲O(nm),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];
}