cp_library_rs/string/
lcs.rs1use crate::chmax;
4
5pub struct LCS<'a, T> {
7 pub A: &'a [T],
8 pub B: &'a [T],
9 pub N: usize,
10 pub M: usize,
11 pub lcs: usize,
12 pub dp: Vec<Vec<usize>>,
13}
14
15impl<'a, T: PartialEq> LCS<'a, T> {
16 pub fn build(A: &'a [T], B: &'a [T]) -> Self {
19 let (N, M) = (A.len(), B.len());
20 let mut dp = vec![vec![0; M + 1]; N + 1];
21
22 for (i, a) in A.iter().enumerate() {
23 for (j, b) in B.iter().enumerate() {
24 if a == b {
25 chmax!(dp[i + 1][j + 1], dp[i][j] + 1);
26 }
27 chmax!(dp[i + 1][j + 1], dp[i + 1][j]);
28 chmax!(dp[i + 1][j + 1], dp[i][j + 1]);
29 }
30 }
31
32 Self {
33 A,
34 B,
35 N,
36 M,
37 lcs: dp[N][M],
38 dp,
39 }
40 }
41
42 pub fn reconstruct(&self) -> Vec<&T> {
45 let mut res = vec![];
46 let mut i = self.N;
47 let mut j = self.M;
48
49 while i > 0 && j > 0 {
50 if self.A[i - 1] == self.B[j - 1] {
51 res.push(&self.A[i - 1]);
52 i -= 1;
53 j -= 1;
54 } else if self.dp[i - 1][j] > self.dp[i][j - 1] {
55 i -= 1;
56 } else {
57 j -= 1;
58 }
59 }
60
61 res.reverse();
62 res
63 }
64}