Skip to content

Commit

Permalink
Add lcs
Browse files Browse the repository at this point in the history
  • Loading branch information
ruthen71 committed Apr 30, 2024
1 parent 247f568 commit 52700fc
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/dp/longest_common_subsequence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Longest Common Subsequence (最長共通部分列)
documentation_of: //dp/longest_common_subsequence.hpp
---
65 changes: 65 additions & 0 deletions dp/longest_common_subsequence.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#pragma once

#include <vector>
#include <string>

template <class T> std::vector<T> longest_common_subsequence(std::vector<T>& a, std::vector<T>& b) {
const int n = (int)(a.size()), m = (int)(b.size());
// -INF
constexpr int e = -1000000000;
std::vector dp(n + 1, std::vector<int>(m + 1, e));
std::vector pd(n + 1, std::vector<int>(m + 1, -1));
// initialize
for (int i = 0; i < n + 1; i++) dp[i][0] = 0;
for (int j = 0; j < m + 1; j++) dp[0][j] = 0;
// dp
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (a[i] == b[j]) {
if (dp[i + 1][j + 1] < dp[i][j] + 1) {
dp[i + 1][j + 1] = dp[i][j] + 1;
pd[i + 1][j + 1] = 0;
}
} else {
if (dp[i + 1][j + 1] < dp[i + 1][j]) {
dp[i + 1][j + 1] = dp[i + 1][j];
pd[i + 1][j + 1] = 1;
}
if (dp[i + 1][j + 1] < dp[i][j + 1]) {
dp[i + 1][j + 1] = dp[i][j + 1];
pd[i + 1][j + 1] = 2;
}
}
}
}
// 復元
std::vector<T> res;
res.reserve(dp[n][m]);
int i = n, j = m;
while (pd[i][j] != -1) {
if (pd[i][j] == 0) {
i--, j--;
res.push_back(a[i]);
} else if (pd[i][j] == 1) {
j--;
} else {
// pd[i][j] == 2
i--;
}
}
std::reverse(res.begin(), res.end());
return res;
}

std::string longest_common_subsequence(std::string& s, std::string& t) {
const int n = (int)(s.size()), m = (int)(t.size());
std::vector<int> a(n), b(m);
for (int i = 0; i < n; i++) a[i] = s[i];
for (int j = 0; j < m; j++) b[j] = t[j];
auto lcs = longest_common_subsequence(a, b);
const int k = (int)(lcs.size());
std::string res;
res.reserve(k);
for (int i = 0; i < k; i++) res += lcs[i];
return res;
}
15 changes: 15 additions & 0 deletions verify/aoj_alds1/aoj_alds1_10_c.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_10_C"

#include <bits/stdc++.h>
#include "dp/longest_common_subsequence.hpp"

int main() {
int N;
std::cin >> N;
for (int i = 0; i < N; i++) {
std::string s, t;
std::cin >> s >> t;
std::cout << longest_common_subsequence(s, t).size() << '\n';
}
return 0;
}

0 comments on commit 52700fc

Please sign in to comment.