代码如下:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int dp[MAXN][MAXN]; // dp[i][j] 表示序列 X 的前 i 个字符和序列 Y 的前 j 个字符的最长公共子序列的长度
int main() {
int T;
cin >> T;
while (T--) {
string X, Y; // 定义字符串 X 和 Y
cin >> X >> Y; // 读入字符串 X 和 Y
int lenX = X.length(), lenY = Y.length();
memset(dp, 0, sizeof(dp)); // 将 dp 数组初始化为 0
for (int i = 1; i <= lenX; i++) { // 枚举 X 的每个字符
for (int j = 1; j <= lenY; j++) { // 枚举 Y 的每个字符
if (X[i-1] == Y[j-1]) { // 如果 X 的第 i 个字符和 Y 的第 j 个字符相等
dp[i][j] = dp[i-1][j-1] + 1; // 那么 X 和 Y 中都包含这个字符,所以 dp[i][j] 的值应该等于 dp[i-1][j-1] + 1
} else {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]); // 最长公共子序列不包含 X[i-1] 或者不包含 Y[j-1],所以 dp[i][j] 的值应该等于 dp[i-1][j] 和 dp[i][j-1] 中的较大值
}
}
}
cout << dp[lenX][lenY] << endl;
}
return 0;
}
图解:
对于这个代码快的图解:
if (X[i-1] == Y[j-1]) { // 如果 X 的第 i 个字符和 Y 的第 j 个字符相等
dp[i][j] = dp[i-1][j-1] + 1; // 那么 X 和 Y 中都包含这个字符,所以 dp[i][j] 的值应该等于 dp[i-1][j-1] + 1
} else {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]); // 最长公共子序列不包含 X[i-1] 或者不包含 Y[j-1],所以 dp[i][j] 的值应该等于 dp[i-1][j] 和 dp[i][j-1] 中的较大值
}
dp[i][j] = dp[i-1][j-1] + 1; 的意思是:如果字符串 X 的第 i 个字符和字符串 Y 的第 j 个字符相等,那么 dp[i][j] 就可以在 dp[i-1][j-1] 的基础上加上一个字符,即 dp[i][j] = dp[i-1][j-1] + 1。
dp[i][j] = max(dp[i-1][j], dp[i][j-1]); 的意思是:如果字符串 X 的第 i 个字符和字符串 Y 的第 j 个字符不相等,那么此时 dp[i][j] 应该取 dp[i-1][j] 和 dp[i][j-1] 中的较大值,即 dp[i][j] = max(dp[i-1][j], dp[i][j-1])。