2huk
2024-11-21 11:26:38
考虑最朴素的 DP。设
直接做是
注意到
满足
注意到对于非特殊状态(
这个过程会持续到
分析复杂度。一个特殊状态会通过两个非特殊状态转移,而一个非特殊状态会通过一个特殊状态转移。所以总复杂度是特殊状态的数量,即
// Problem:
// T541528 左右互搏术
//
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/T541528?contestId=214582
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// #define tests
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, a[N], b[N];
int na[N], nb[N]; // a, b 的逆
int g[N];
vector<int> pos[N * 2]; // 每种差的出现位置
int dp(int x, int y) {
if (!x) return y;
if (!y) return x;
if (a[x] == b[y]) {
if (~g[x]) return g[x];
return g[x] = min({dp(x - 1, y - 1) + 2, dp(x, y - 1) + 1, dp(x - 1, y) + 1});
}
auto it = lower_bound(pos[x - y + N].begin(), pos[x - y + N].end(), x);
if (it == pos[x - y + N].begin()) return max(x, y);
it -- ;
return dp(*it, *it + y - x) + x - *it;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; ++ i ) cin >> a[i], na[a[i]] = i;
for (int i = 1; i <= n; ++ i ) cin >> b[i], nb[b[i]] = i;
for (int i = 0; i <= n; ++ i ) {
f[0][i] = f[i][0] = i;
}
for (int i = 1; i <= n; ++ i ) {
pos[na[i] - nb[i] + N].push_back(na[i]);
}
for (int i = 0; i < N * 2; ++ i ) {
sort(pos[i].begin(), pos[i].end());
}
memset(g, -1, sizeof g);
cout << dp(n, n) << '\n';
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
#ifdef tests
cin >> T;
#endif
while (T -- ) solve();
return 0;
}