풀이 주석참조

def solve(depth):
    global result
    # depth를 포지션으로 정의 depth가 11이 되면, 포지션이 꽉 찬 상태
    if depth == 11:
        # 지금까지 넣어논 선수의 능력치를 모두 더한값을 정해주고 return
        result = max(result, sum(ans))
        return
    # 여기서 사용하는 i는 배열의 열, 행은 depth로 정의 즉, 배열의 열이 하나 있다면, 다른 행의 요소는 열 번호가 달라야함
    for i in range(11):
        if visited[i]:
            continue
        # 0이 아니라면
        if skill[depth][i]:
            visited[i] = 1
            ans.append(skill[depth][i])
            solve(depth+1)
            # 마지막 원소를 pop하며 다시 전으로 return됨
            ans.pop()
            visited[i] = 0

for tc in range(int(input())):
    skill = [list(map(int, input().split())) for _ in range(11)]

    result = 0
    ans = []
    # visited는 선수가 포지션에 있는지 확인 여부 (배열의 열을 쓰고 있는지)
    visited = [0]*12
    solve(0)
    print(result)

 

해설

  • N과 M문제를 응용해서 풀 수 있는 탐색, 백트래킹 문제였다.
  • 이 문제에서는 depth를 선수의 포지션이 하나씩 정해주는 것을 뜻한다.
  • 즉, depth를 열번호로 사용한다. 하나의 열에 요소가 있으면, 다른 요소를 사용해야 한다.
  • 첫번째 행에서 요소를 정하고, 다음 행에서 요소를 정할 때 그 요소가 있는 열은 사용하지 못한다.
  • 트리로 그려본다면 밑 그림과 같다.

  • 그림에서 첫 번째 행에서 1을 정해주고 두번째 행에서 사용 가능한 요소는 6, 7, 8이다.
  • 이런식으로 밑으로 내려가고, 밑에 더이상 값이 없으면(depth==M)이 되면, return한다.
  • 1, 6, 11, 1, 6, 12, 1, 7, 10, 1, 7, 12, 1, 8, 10, 1, 8, 11 순서로 탐색할 것이다.
  • 1에서 8이 return해 오면 더이상 들어갈 곳이 없으니 첫 번째 행은 다음 요소 2를 잡고 같은 과정을 반복한다.

'백준' 카테고리의 다른 글

백준 2146 다리 만들기 (파이썬)  (0) 2022.09.24
백준 1918 후위 표기식 (파이썬)  (0) 2022.09.20
백준 5427 불 (파이썬)  (0) 2022.09.18
백준 N과 M 3~12 (파이썬)  (0) 2022.09.17
백준 15650 N과 M (2) (파이썬)  (0) 2022.09.15
복사했습니다!