(전공복습) 데이터과학 4. 시각화
차례
간단한 DP 문제.
실질적인 m
의 최대치는 6이고, \(_{6}C_{2} = 15\)이므로 단순한 완전탐색은 \(15^{10}\)으로 시간초과이다.
아이디어는, 어차피 숫자를 배열하는 경우의 수는 기껏해야 \(6! = 720\)가지이고, 즉 아무리 넓게 잡아도 \(720 \times 10 = 7200\)가지 문제에 대한 답만 알고 있으면 언제든지 입력에 대한 정답을 구할 수 있다는 것이다.
그러니까, 가능한 모든 경우를 탐색하다 DP 메모이제이션을 통해서 이미 구한 n
과 k
에 대해서는 다시 계산하지 않으면 된다.
추가로, 구현에 있어서 간편하게 functools.cache
데코레이터를 사용했고, 어차피 두 자연수 a
와 b
에 대해 자릿수가 같으면 a > b == str(a) > str(b)
이므로 그냥 문자열을 그대로 사용했다.
그 외에 첫글자가 0이 되는 경우의 수를 제거해주는 것까지 체크하면 크게 어려울 것 없다.
#!python
from functools import cache
# 입력이 n, k일 때의 정답을 반환
# n, k가 동일하다면 무조건 답도 동일하므로 메모이제이션한다
@cache
def solve(n, k):
# k == 0이면 바꿀 게 없으므로 n이 정답
if not k:
return n
# 처음엔 '0'으로 이루어진 문자열로 초기화
ret = zeros
# 가능한 모든 경우 탐색
for i in range(l):
for j in range(i + 1, l):
# s는 n[i], n[j]를 스왑한 문자열
s = n[:i] + n[j] + n[i+1:j] + n[i] + n[j+1:]
# 첫 글자가 0인 케이스는 안된다
if s[0] == '0':
continue
# 가능한 경우 중 최대값을 반환
ret = max(ret, solve(s, k - 1))
# 초기화 이후로 문자열이 안 바뀜 == 바꾸는 게 불가능 == -1이 답
return ret if ret != zeros else '-1'
# n은 문자열 그대로 처리해도 큰 상관 없다
# 어차피 같은 자리 양수 a, b에 대해 a > b == str(a) > str(b)임
n, k = input().split()
k = int(k)
# l은 총 자릿수, zeros는 정답 초기화를 위한 문자열
l = len(n)
zeros = '0' * l
print(solve(n, k))
문제 링크 문제 링크
개요 선형적인 자료구조에서는 값에 접근하는 데에 \(O(1)\)이면 충분하지만, 대신 부분합을 구하는 데에는 \(O(N)\)이 필요하다. 그렇다면 이 자료구조를 이진 트리로 구성하면 어떨까? 값에 접근하는 데에 걸리는 시간이 \(O(\lg N)\)으로 늘어나지만 대신 부분합을 구하...
개요 다익스트라 알고리즘과 함께 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 다익스트라 알고리즘보다 느리지만, 음수 가중치 간선이 있어도 작동하며, 음수 가중치 사...
개요 다익스트라 알고리즘은 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘 중 하나이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 단, 다익스트라 알고리즘은 음수 가중치 엣지를 허용하지 않는다. 이 경우에는 벨만-...