Description
给出两个由小于等于 (k) 的正整数构成的数列 (A) 与 (B) ,长度为 (n) 与 (m) 。
现在需要一个由小于等于 (k) 的正整数构成的数列 (C) ,使得 (C) 既不是 (A) 的子序列,也不是 (B)
的子序列。
请求出 (C) 的最小长度。
(n,m,kle 4000)
Solution
(dp[i][j]) 表示 (A) 扫到 (i) , (B) 扫到 (j) , (C) 的最小长度。
预处理一下下一个与当前位置值相同的位置就好了。
#include<bits/stdc++.h>
using namespace std;
template <class T> inline void read(T &x) {
x = 0; static char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >= '0' && ch <= '9'; ch = getchar()) (x *= 10) += ch - '0';
}
#define N 4010
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define drp(i, a, b) for (int i = a; i >= b; i--)
int n, m, K, a[N], b[N], dp[N][N], f1[N][N], f2[N][N], ans;
inline void upd(int& x, int y) { if (!x || x > y) x = y; }
int main() {
read(n), read(m), read(K);
rep(i, 1, n) read(a[i]);
rep(i, 1, m) read(b[i]);
drp(i, n, 1) {
rep(j, 1, K) f1[i][j] = f1[i + 1][j];
f1[i][a[i]] = i;
}
drp(i, m, 1) {
rep(j, 1, K) f2[i][j] = f2[i + 1][j];
f2[i][b[i]] = i;
}
dp[0][0] = 1, ans = min(n, m) + 1;
rep(i, 0, n) rep(j, 0, m) if (a[i] == b[j] && dp[i][j]) rep(k, 1, K)
if (!f1[i + 1][k] && !f2[j + 1][k]) ans = min(ans, dp[i][j]);
else upd(dp[f1[i + 1][k]][f2[j + 1][k]], dp[i][j] + 1);
printf("%d", ans);
return 0;
}