题解:P12738 [POI 2016 R2] 口吃 Stutter
block_in_mc · · 题解
首先考虑一个时空复杂度都是
首先求出
-
- 特别地,若
a_{i+1}=b_{j+1} ,则dp_{nxta_{i+1},nxtb_{j+1}}\leftarrow dp_{i,j}+2 。
由于空间限制只有 32MB,而当前的状态转移又无法进行滚动数组优化,考虑重新设计状态。
仔细分析转移过程,考虑如何将第二步写成能够滚动数组优化的形式。现在的转移过程是
这样我们只会从
::::info[AC 代码] Submission
#include <bits/stdc++.h>
using namespace std;
int n, m, a[16000], b[16000], nxta[16000], nxtb[16000], pre[16000][2], dp[16000][2], nxt[16000][2];
map<int, int> mp;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++)
cin >> b[i];
for (int i = m; i >= 1; i--) {
if (mp[b[i]]) nxtb[i] = mp[b[i]];
mp[b[i]] = i;
}
for (int i = 0; i <= m; i++)
pre[i][1] = -0x3f3f3f3f;
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++)
dp[j][0] = dp[j][1] = -0x3f3f3f3f;
for (int j = 0; j <= m; j++) {
pre[j + 1][0] = max(pre[j + 1][0], pre[j][0]);
dp[j][0] = max(dp[j][0], pre[j][0]);
if (a[i + 1] == b[j + 1] && nxtb[j + 1]) dp[nxtb[j + 1]][1] = max(dp[nxtb[j + 1]][1], pre[j][0]);
if (a[i + 1] == b[j]) dp[j][0] = max(dp[j][0], pre[j][1] + 2);
else dp[j][1] = max(dp[j][1], pre[j][1]);
}
for (int j = 0; j <= m; j++)
pre[j][0] = dp[j][0], pre[j][1] = dp[j][1];
}
cout << max(pre[m][0], pre[m][1]);
return 0;
}
::::