(전공복습) 데이터과학 4. 시각화
차례
다이나믹 프로그래밍을 활용하는 문제.
dp[i][j]
는 두 문자열 a
, b
에 대해 a[...i]
, b[...j]
의 LCS가 된다.
따라서 초항은 a[0] == b[0]
이면 1
, 아니면 0
이 된다.
그리고 각 첫 줄은 a[0] == b[0]
이면 1
, 아니면 줄의 이전 항이 된다.
그리고 그 외의 경우 점화식은 다음과 같다:
a[i] == b[j]
인 경우 : dp[i][j] = dp[i-1][j-1] + 1
a[i] != b[j]
인 경우 : dp[i][j] = max(dp[i-1][j], dp[i][j-1])
그 이유는 이렇다:
a[i] == b[j]
인 경우 직전 문자열 a[...i-1]
과 b[...j-1]
의 LCS에다가 a[i]
를 더한 것이 되기 때문이고,
a[i] != b[j]
인 경우 a[...i-1]
과 b[...j]
, a[...i]
과 b[...j-1]
의 LCS 중 큰 것이 그대로 유지되기 때문이다(Longest이므로 큰 것이 유지된다는 뜻이다).
a = input()
b = input()
n = len(a)
m = len(b)
dp = [[(0, '')] * m for _ in range(n)]
# 초항
dp[0][0] = (1, a[0]) if a[0] == b[0] else (0, '')
# x, y축의 첫 줄 DP
for i in range(n):
dp[i][0] = (1, b[0]) if a[i] == b[0] else dp[i-1][0]
for j in range(m):
dp[0][j] = (1, a[0]) if a[0] == b[j] else dp[0][j-1]
# DP
for i in range(1, n):
for j in range(1, m):
# a[i] == b[j]인 경우
if a[i] == b[j]:
dp[i][j] = (dp[i-1][j-1][0] + 1, dp[i-1][j-1][1] + a[i])
# a[i] != b[j]인 경우
else:
if dp[i][j-1] > dp[i-1][j]:
dp[i][j] = (dp[i][j-1][0], dp[i][j-1][1])
else:
dp[i][j] = (dp[i-1][j][0], dp[i-1][j][1])
# dp[i][j] = dp[i-1][j-1] + 1 if a[i] == b[j] else max(dp[i][j-1], dp[i-1][j])
print(dp[-1][-1][0])
if dp[-1][-1][0]:
print(dp[-1][-1][1])
문제 링크 문제 링크
개요 선형적인 자료구조에서는 값에 접근하는 데에 \(O(1)\)이면 충분하지만, 대신 부분합을 구하는 데에는 \(O(N)\)이 필요하다. 그렇다면 이 자료구조를 이진 트리로 구성하면 어떨까? 값에 접근하는 데에 걸리는 시간이 \(O(\lg N)\)으로 늘어나지만 대신 부분합을 구하...
개요 다익스트라 알고리즘과 함께 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 다익스트라 알고리즘보다 느리지만, 음수 가중치 간선이 있어도 작동하며, 음수 가중치 사...
개요 다익스트라 알고리즘은 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘 중 하나이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 단, 다익스트라 알고리즘은 음수 가중치 엣지를 허용하지 않는다. 이 경우에는 벨만-...