#include <map>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
int longestCommonSubsequenceHelper(string &A, string &B, int ia, int ib, vector<vector<int>> &dp) {
if (ia == A.size() || ib == B.size()) {
return 0;
}
if (dp[ia][ib] != 0) {
return dp[ia][ib];
}
if (A[ia] == B[ib]) {
return 1 + longestCommonSubsequenceHelper(A, B, ia + 1, ib + 1, dp);
}
int left = longestCommonSubsequenceHelper(A, B, ia + 1, ib, dp);
int right = longestCommonSubsequenceHelper(A, B, ia, ib + 1, dp);
return dp[ia][ib] = max(left, right);
}
/* 动态规划五部曲
* 1、dp[i][j] (i..end)(j...end)的最长公共子序列
* 2、状态转移方程: dp[i][j] = dp[i + 1][j + 1] + 1 (A[i] == B[j])
* dp[i][j] = max(dp[i + 1][j], dp[i][j + 1])
* 3、 初始化 都为0
* 4、 遍历顺序逆序
* 5、 从头到位模拟一遍
* */
int longestCommonSubsequenceLooper(string &A, string &B) {
vector<vector<int>> dp(A.size() + 1, vector<int>(B.size() + 1));
for (int i = A.size() - 1; i >= 0; --i) {
for (int j = B.size() - 1; j >= 0; --j) {
if (A[i] == B[j]) {
dp[i][j] = dp[i + 1][j + 1] + 1;
} else {
dp[i][j] = max(dp[i + 1][j], dp[i][j + 1]);
}
}
}
for (auto &vec : dp) {
for (auto v : vec) {
cout << v << "\t";
}
cout << endl;
}
return dp[0][0];
}
/* 动态规划五部曲
* 1. dp[i][j] 前i,前j序列的最长公共子序列
* 2. dp[i][j] = dp[i - 1][j - 1] (A[i] == B[j])
* dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
* 3. 初始化 全部为0
* 4. 遍历顺序 从前往后
* 5. 模拟
* */
int longestCommonSubsequenceLooper2(string &A, string &B) {
vector<vector<int>> dp(A.size() + 1, vector<int>(B.size() + 1));
for (int aIndex = 0; aIndex < A.size(); ++aIndex) {
for (int bIndex = 0; bIndex < B.size(); ++bIndex) {
if (A[aIndex] == B[bIndex]) {
dp[aIndex + 1][bIndex + 1] = dp[aIndex][bIndex] + 1;
} else {
dp[aIndex + 1][bIndex + 1] = max(dp[aIndex + 1][bIndex], dp[aIndex][bIndex + 1]);
}
}
}
return dp.back().back();
}
/* 滚动数组
* dp[i] 前i,(0 - j)的最长公共子序列
* int last 额外记录
*
* */
int longestCommonSubsequenceLooper3(string &A, string &B) {
vector<int> dp(A.size() + 1);
for (int bIndex = 0; bIndex < B.size(); ++bIndex) {
int last = dp[0];
for (int aIndex = 0; aIndex < A.size(); ++aIndex) {
// 斜对角的值
int temp = dp[aIndex + 1];
if (A[aIndex] == B[bIndex]) {
dp[aIndex + 1] = last + 1;
} else {
dp[aIndex + 1] = max(dp[aIndex + 1], dp[aIndex]);
}
last = temp;
}
}
return dp.back();
}
int longestCommonSubsequence(string &A, string &B) {
return longestCommonSubsequenceLooper3(A, B);
}
};
int main() {
string A = "ABCD";
string B = "EACB";
cout << Solution{}.longestCommonSubsequence(A, B) << endl;
}
c++-动态规划算法-最长公共子序列
最新推荐文章于 2024-05-18 15:20:39 发布