💡 백트레킹
해를 찾는 도중 해가 아니어서 막히면 되돌아가서 다시 해를 찾아가는 기법
(모든 경우의 수를 탐색하는 대신, 조건을 걸어 유망한 경우로 탐색하기)불필요한 부분을 줄이고 최대한 올바른 쪽으로 간다!
→ 특정한 조건을 만족하는 경우만 살펴보는 것
DFS는 가능한 모든 경로를 탐색하므로 경우의 수를 줄이지 못한다.
N! 가지의 경우의 수를 가진 문제는 DFS로 풀지 못함!
조건문 등을 걸어서 답이 절대 될 수 없는 상황을 정의
→ 그러한 상황일 때 탐색 중지, 그 이전으로 돌아가 다른 경우 탐색하게끔
def backTracking () :
if len(s) == m : # m개가 쌓이면 출력
print(' '.join(map(str, s)))
return
for i in range(1, n+1) :
if visited[i] :
continue
visited[i] = True
s.append(i)
backTracking()
s.pop()
visited[i] = False
n, m = map(int, input().split())
s = []
visited = [False] * (n+1)
backTracking()
n = 4, m = 2일 경우 실행될 코드를 한 줄씩 풀어본다면 아래와 같다.
n = 4
m = 2
visited = [False, False, False, False, False]
backtracking() ->
len(s) => 0. if문 넘어감
i = 1
visited => False이므로 if조건 해당 안됨
visited[1] = True
s.append(1)
backTracking()
len(s) => 1. if문 넘어감
i = 1
visited[1] => True이므로 if조건 해당됨
i = 2
visited => False이므로 if조건 해당 안됨
visited[2] = True
s.append(2)
backTracking()
len(s) => 2. if문 들어감
print -> “1 2”
return
s.pop() =====> 1
visited[2] = False
i = 3
visited[3] => False이므로 if조건 해당 안됨
visited[3] => True
s.append(3) ========> 1 3
backTracking()
len(s) => 2. if문 들어감
print -> “1 3”
return
s.pop() ======> 1
visited[3] = False =====> [False, true, false, false, false]
i = 4
visited[4] => False이므로 if조건 해당 안됨
visited[4] => True
s.append(4) ========> 1 4
backTracking()
len(s) => 2. if문 들어감
print -> “1 4”
return
s.pop() ======> 1
visited[4] = False =====> [False, True, False, False, False]
s.pop() ======> []
visited[1] = False ========> [False, False, False, False, False]
i = 2
visited => False이므로 if조건 해당 안됨
visited[2] = True
s.append(2) ========> [2]
backTracking()
len(s) => 1. if문 넘어감
i = 1
visited[1] => False이므로 if조건 해당안됨
visited[1] = True
s.append(1) ========> [2, 1]
backTracking()
len(s) => 2. if문 들어감
print -> “2 1”
return
s.pop() =====> 2
visited[1] = False
i = 2
visited => True이므로 if조건 해당 됨
i = 3
.
.
.