DP的模板题
将s1作为短的字符串,s2作为长的字符串。
考虑空间复杂度n*m的做法,定义dp[n][m],dp[i][j]表示考虑s2的前 i 位和s1的前 j 位的最长公共子序列的结果
状态转移:
if (s2[i] == s1[j]) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + 1);
else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
考虑到在转移方程中,只存在两行数组之间的转换,既只有dp[i][*]和dp[i - 1][*]的转换。可以使用一个两行的数组来代替整个数组。既可以做到时间复杂度min(n, m);
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
string s1, s2;
cin >> s1 >> s2;
if(n > m) {
int t = n;
n = m;
m = t;
string x = s1;
s1 = s2;
s2 = x;
}
vector<vector<int>> dp(2, vector<int>(n + 1, 0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (s2[i] == s1[j]) {
dp[1][j + 1] = max(dp[0][j + 1], dp[0][j] + 1);
} else {
dp[1][j + 1] = max(dp[0][j + 1], dp[1][j]);
}
}
for (int j = 0; j <= n; j++) {
dp[0][j] = dp[1][j];
}
}
cout << dp[0][n] << '\n';
}



京公网安备 11010502036488号