【AtCoder】ABC 185 E - Sequence Matching

実行時間制限: 2 sec / メモリ制限: 1024 MiB / Difficulty: 1468 / NoviSteps: 1Q / 配点: 500 点
問題概要
長さ の整数列 と、長さ の整数列 がある。
高橋君は からいくつかの要素を取り除き、残った要素をそのままの順番で繋げることで新たな数列 を作る(一つも取り除かなくても、全部取り除いても構わない)。 についても同様に、いくつかの要素を取り除き、残った要素をそのままの順番で繋げることで新たな数列 を作る(一つも取り除かなくても、全部取り除いても構わない)。 このとき、 となるような取り除き方をする。
から取り除いた合計要素数を とし、 かつ を満たす整数 の数を とするとき、 として考えられる最小の値を求めよ。
制約
- 入力は全て整数
考察
問題文が分かりにくいが、 を へ一致させるための操作回数を求める問題であると考えると、理解しやすい。 いわゆる「編集距離」の問題である。
具体的には、以下のようになる。
- の要素を削除する → 削除
- の要素を削除する → 挿入
- と の対応する要素が異なる → 置換
したがって、
と定義すると、先ほどの3つの操作それぞれに対する漸化式は
- の要素を削除する:
- の要素を削除する:
- と の対応する要素が異なる:
となるから、これらを組み合わせると、
となる。
また、初期値は で、最終的な答えは とすればよい。
計算量は である。
実装例
1.#include <bits/stdc++.h>2.using namespace std;3. 4.#define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++)5. 6.constexpr int INF = 1e+9;7. 8.// ======================================== //9. 10.int main()11.{12. int N, M;13. cin >> N >> M;14. vector<int> A(N), B(M);15. rep(i, 0, N) cin >> A[i];16. rep(i, 0, M) cin >> B[i];17. 18. vector<vector<int>> dp(N + 1, vector<int>(M + 1, INF));19. rep(i, 0, N + 1) dp[i][0] = i;20. rep(j, 0, M + 1) dp[0][j] = j;21. 22. rep(i, 1, N + 1) rep(j, 1, M + 1)23. {24. dp[i][j] = min({25. dp[i - 1][j] + 1,26. dp[i][j - 1] + 1,27. dp[i - 1][j - 1] + (A[i - 1] != B[j - 1])28. });29. }30. 31. cout << dp[N][M] << endl;32. 33. return 0;34.}実装時間: 30 分
コメント
の削除操作を への挿入操作と捉えるのがポイント。





