๋ฌธ์ ์ ๋ฆฌ
LCS(Longest Common Subsequence, ์ต์ฅ ๊ณตํต ๋ถ๋ถ ์์ด) ๋ฌธ์
๋ ์์ด์ด ์ฃผ์ด์ง๋ค.
๋ถ๋ถ ์์ด์ ์ฐพ๋๋ค.
๊ทธ ์ค ๊ฐ์ฅ ๊ธด ๊ฒ์ ์ฐพ๋๋ค.
์๋ฅผ ๋ค์ด, ACAYKP์ CAPCAK์ LCS๋ ACAK๊ฐ ๋๋ค.
LCS์ ๊ธธ์ด์ LCS๋ฅผ ์ถ๋ ฅํ๋ค.
์ ํ ์ฌํญ
0.1s, java11: 0.4s
๊ฐ ์์ด = ์ต๋ 1000๊ธ์
LCS๊ฐ 0์ธ ๊ฒฝ์ฐ, ๊ธธ์ด๋ง ์ถ๋ ฅ
ํต์ฌ ํฌ์ธํธ
LCS๋ฅผ naiveํ๊ฒ ์ฐพ์๋ณด์.
- A ์์ด๊ณผ B ์์ด์ด ์์ ๋, B ์์ด๋ก A ์์ด์ LCS๋ฅผ ์ฐพ๋๋ค๋ฉด O(N^3)์ด ๋ฐ์ํ๋ค.
- B ์์ด์ ๊ฐ ๊ธ์๋ฅผ ์ฒซ ๋ถ๋ถ ์์ด์ ๊ธ์๋ก ์๊ฐํ๊ณ ์ฐพ๋๋ค๋ฉด 1000 ๊ธ์์ ๋ํด ๊ฐ ๊ฐ 1000 - i ๊ธ์ ์๋ฅผ ์ฐ์ฐํด์ผ ๋๋ค. (N^2)
- ๊ฐ N^2์ ๋ถ๋ถ ์์ด์ ๊ธ์๊ฐ A ์์ด์ ์๋์ง ํ์ธํด์ผํ๋ค. (N^3)
- ์์ ํ์์ผ๋ก๋ ๋ถ๊ฐ๋ฅ ํ ๊ฒ์ ์๊ฒ ๋๋ค.
DP ๋๋ ๊ทธ๋ฆฌ๋, ์ด๋ถ ํ์๊ณผ ๊ฐ์ ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํด์ผ๋๋ค.
ํด๋น ๋ฌธ์ ๋ ์ ๋ช
ํ LCS ๋ฌธ์ ๋ผ์ DP์ธ ๊ฒ์ ์๋ช
ํ๋ค.
ํ์ง๋ง, ์ฒ์ ๋ฌธ์ ๋ฅผ ๋ดค์ ๋ DP์ธ์ง ์ด๋ป๊ฒ ์ ์ ์์๊น?
ํค ํฌ์ธํธ๊ฐ 3๊ฐ์ง ์๋ค.
- ๋ถ๋ถ ์์ด -> B ์์ด ์ค ์ ๋ถ๋ถ์ ์์ ์์ด์ ๋ค์ ๊ธ์๋ฅผ ์ถ๊ฐํ๋ค๋ฉด ๋ฉ๋ชจ์ ์ด์ ์ ํ์ฉํ ์ ์๋ค.
- ๊ฐ์ฅ ๊ธด -> ์ต์ฅ์ ์ฐพ๋ ๋ฌธ์ ์์๋ DP๋ฅผ ์์ฌํ ์ ์๋ค.
- ์๊ฐ ์ ํ -> ์ฑ 1์ด๋ ์๋๋ ์งง์ ์๊ฐ์ ์ ํ ํ์์ด๋ ์์ ํ์์์ ์ฃผ๋ก ๋์จ๋ค. DP๋ฅผ ์์ฌํ ์ ์๋ค.
ํต์ฌ ๋ก์ง
DP ํ ์ด๋ธ์ ๊ทธ๋ ค๋ณด๋ฉด, ๊ทธ๋ฆผ๊ณผ ๋์ผํ๋ค. ACAYKP ์์ ๋ฐ๋ผ๋ณด์.
A๊ฐ CAPCAK์์ A๋ฅผ ๋ง๋ ์๊ฐ๋ถํฐ LCS๋ 1์ด๋ค.
C๋ ์ด์ ์ A์ LCS๊ฐ ์๊ธฐ ๋๋ฌธ์, CAPCAK์์ C๋ฅผ ๋ง๋์ง ๋ชปํ๋ค๋ฉด ๋ถ๋ถ ์์ด A์ LCS๊ฐ AC์ LCS๊ฐ ๋ ๊ฒ์ด๋ค.
๋ง์ฝ, C๋ฅผ ๋ง๋๋ค๋ฉด C๋ฅผ ๋ง๋ ์์ (๋ฐ๋ก ์ด์ ๋ถ๋ถ ์์ด)๊น์ง์ LCS + 1 ๊ฐ์ด๋ค.
์ฆ 2๊ฐ์ง ์ผ์ด์ค๋ง ์กด์ฌํ๋ฏ๋ก ์ ํ์์ ๋์ถ ํ ์ ์๋ค.
if ch1 == ch2 DP[i][j] = DP[i-1][j-1] + 1
else DP[i][j] = max(DP[i-1][j], DP[i][j-1])
๊ทธ๋ผ, LCS์ ๋ฌธ์๋ฅผ ๋ฝ์๋ด๋ ค๋ฉด ์ด๋ป๊ฒ ํ ์ ์์๊น? -> trace
๋ ์์ด์ ๊ธธ์ด๋ถํฐ ์์ํด์ dp ํ ์ด๋ธ์ ํตํด ์ถ์ ํ ์ ์๋ค.
if (A์ B์ ๊ธธ์ด๊ฐ ๊ฐ๊ฐ <= 0) return
else if (๋ฌธ์๊ฐ ๊ฐ๋ค๋ฉด) ๋ฌธ์ ์ ์ฅ
else DP ํ ์ด๋ธ์์ A, B๋ฅผ ํตํ ๊ฒฝ๋ก ์ค ๋ ํฐ ๊ฐ์ผ๋ก ์ถ์
์ฝ๋
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static StringBuilder sb = new StringBuilder();
static int[][] dp = new int[1001][1001];
static String str1, str2;
public static void main(String[] args) throws IOException {
str1 = br.readLine();
str2 = br.readLine();
for (int i = 0; i < str1.length(); i++) {
for (int j = 0; j < str2.length(); j++) {
if (str1.charAt(i) == str2.charAt(j)) {
dp[i + 1][j + 1] = dp[i][j] + 1;
} else {
dp[i+1][j+1] = Math.max(dp[i][j+1], dp[i+1][j]);
}
}
}
int maxLcsLength = dp[str1.length()][str2.length()];
sb.append(maxLcsLength).append('\n');
trace(str1.length(), str2.length());
bw.write(sb.toString());
bw.flush();
}
static void trace(int s1Idx, int s2Idx) {
if (s1Idx <= 0 || s2Idx <= 0) {
return;
} else if (str1.charAt(s1Idx - 1) == str2.charAt(s2Idx - 1)) {
trace(s1Idx - 1, s2Idx - 1);
sb.append(str1.charAt(s1Idx - 1));
} else if (dp[s1Idx - 1][s2Idx] >= dp[s1Idx][s2Idx - 1]) {
trace(s1Idx - 1, s2Idx);
} else {
trace(s1Idx, s2Idx - 1);
}
}
}
'์๊ณ ๋ฆฌ์ฆ > ๋ฐฑ์ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[BOJ 17406] ๋ฐฐ์ด ๋๋ฆฌ๊ธฐ 4 (0) | 2025.04.03 |
---|---|
[BOJ 1826] ์ฐ๋ฃ ์ฑ์ฐ๊ธฐ (0) | 2025.03.31 |
[BOJ 20207] ๋ฌ๋ ฅ (0) | 2025.03.31 |
๋ฐฑ์ค - [BOJ 22856] ํธ๋ฆฌ ์ํ (0) | 2024.07.08 |
๋ฐฑ์ค - [BOJ 1865] ์ํ (0) | 2024.07.06 |