POJ 1159
这一题的关键是 最长公共子序列
我并没有想到… 然后呢, 在纸上模拟补齐, 嗯…
举个例子,
Aba3bd
和它的倒序db3abA
, 它们的最长公共子序列是b3b
, 所以只要最长的公共子序列对齐即可1 2 | A b a 3 b d d b 3 a b A |
只要对齐的字符越多, 要补的字符就越少
然后中间空出来的部分, 照抄上面的或者下面的
两边不同的部分, 直接错开对齐就行
两边不同的部分, 直接错开对齐就行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | using namespace std; int main() { int n; cin >> n; string data; cin >> data; data = " " + data; static short dp[5050][5050]; memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if (data[i] == data[n - j + 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]); } } } cout << n - dp[n][n] << endl; return 0; } |
滚动数组版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using namespace std; int main() { int n; cin >> n; string data; cin >> data; data = " " + data; int dp[2][5050]; memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if (data[i] == data[n - j + 1]) { dp[i % 2][j] = dp[(i+1) % 2][j - 1] + 1; } else { dp[i % 2][j] = max(dp[i % 2][j - 1], dp[(i+1) % 2][j]); } } } cout << n - dp[n % 2][n] << endl; return 0; } |