본문 바로가기
백준/백트래킹

[백준🥇5] #3980 선발 명단 (Python)

by 똥먹는낙타 2023. 2. 28.
728x90
반응형

https://www.acmicpc.net/problem/3980

 

3980번: 선발 명단

각각의 테스트 케이스에 대해서, 모든 포지션의 선수를 채웠을 때, 능력치의 합의 최댓값을 한 줄에 하나씩 출력한다. 항상 하나 이상의 올바른 라인업을 만들 수 있다.

www.acmicpc.net

문제

챔피언스 리그 결승전을 앞두고 있는 맨체스터 유나이티드의 명장 퍼거슨 감독은 이번 경기에 4-4-2 다이아몬드 전술을 사용하려고 한다.

오늘 결승전에 뛸 선발 선수 11명은 미리 골라두었지만, 어떤 선수를 어느 포지션에 배치해야 할지 아직 결정하지 못했다.

수석코치 마이크 펠란은 11명의 선수가 각각의 포지션에서의 능력을 0부터 100까지의 정수로 수치화 했다. 0은 그 선수가 그 포지션에 적합하지 않다는 뜻이다.

이때, 모든 선수의 포지션을 정하는 프로그램을 작성하시오. 모든 포지션에 선수를 배치해야 하고, 각 선수는 능력치가 0인 포지션에 배치될 수 없다.

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 첫째 줄에는 테스트 케이스의 개수 C가 주어진다. 각각의 케이스는 11줄로 이루어져 있고, i번 줄은 0과 100사이의 11개의 정수 sij를 포함하고 있다. sij는 i번선수가 j번 포지션에서 뛸 때의 능력이다. 모든 선수에게 적합한 포지션의 수는 최대 5개이다. (능력치가 0보다 크다)

출력

각각의 테스트 케이스에 대해서, 모든 포지션의 선수를 채웠을 때, 능력치의 합의 최댓값을 한 줄에 하나씩 출력한다. 항상 하나 이상의 올바른 라인업을 만들 수 있다.

예제 입력 1

1
100 0 0 0 0 0 0 0 0 0 0
0 80 70 70 60 0 0 0 0 0 0
0 40 90 90 40 0 0 0 0 0 0
0 40 85 85 33 0 0 0 0 0 0
0 70 60 60 85 0 0 0 0 0 0
0 0 0 0 0 95 70 60 60 0 0
0 45 0 0 0 80 90 50 70 0 0
0 0 0 0 0 40 90 90 40 70 0
0 0 0 0 0 0 50 70 85 50 0
0 0 0 0 0 0 66 60 0 80 80
0 0 0 0 0 0 50 50 0 90 88

예제 출력 1

970

✔️ Code

import sys
input = sys.stdin.readline

c = int(input()) # 테스트 케이스 개수

def backtracking(cnt, sum):
    global result
    if cnt == 11:
        result = max(result, sum)
        return

    for i in range(11):
        # 이미 포지션이 있는 멤버이거나 해당 포지션의 능력치가 0일 때
        if members[i] or not powers[cnt][i]:
            continue

        members[i] = 1
        backtracking(cnt + 1, sum + powers[cnt][i])
        members[i] = 0

for _ in range(c):
    powers = [list(map(int, input().split())) for _ in range(11)]
    members = [0 for _ in range(11)] # 멤버 체크
    result = 0

    backtracking(0, 0)
    print(result)

✏️ Comment

CNS 코테 직후에 톡방에서 이 문제가 내가 못 풀었던 2번 백트래킹 문제와 유사하다는 말이 나와서 한 번 도전해봤다. 근데 역시나 한 번에는 못 풀어서 ㅎ.. 구글링 좀 했다. 개인적으로 powers[cnt][i]와 같은 부분들을 생각해내기가 좀 힘든 것 같다.

💡 Check

백트래킹을 할 때 아래의 두 가지 조건에 해당되면 continue로 넘어가는 것이 핵심이다.

  • 이미 포지션이 배정된 멤버일 경우 : members[i] == 1
  • 현재 멤버의 해당 포지션에 대한 능력치가 0일 경우 : powers[cnt][i] == 0

cnt == 11이라면 모든 멤버들의 포지션이 배정되었다는 뜻이므로, 능력치의 합을 계산해서 현재의 값과 비교하여 max 값을 교체해준다.

728x90
반응형

댓글