PCCP 모의고사 1회차 - 2번 문제

PCCP 모의고사 1회차 - 2번 문제

코딩테스트 준비

해당 썸네일은 Wonkook Lee 님이 만드신 Thumbnail-Maker 를 이용하였습니다

Hits

바로 문제로 들어가자

🥢 문제

당신이 다니는 학교는 매년 체육대회를 합니다. 체육대회는 여러 종목에 대해 각 반의 해당 종목 대표가 1명씩 나와 대결을 하며, 한 학생은 최대 한개의 종목 대표만 할 수 있습니다. 당신의 반에서도 한 종목당 1명의 대표를 뽑으려고 합니다.

학생들마다 각 종목에 대한 능력이 다르지만 이 능력은 수치화되어 있어 미리 알 수 있습니다. 당신의 반의 전략은 각 종목 대표의 해당 종목에 대한 능력치의 합을 최대화하는 것입니다.

다음은 당신의 반 학생이 5명이고, 종목의 개수가 3개이며, 각 종목에 대한 학생들의 능력치가 아래 표와 같을 때, 각 종목의 대표를 뽑는 예시입니다.

학생테니스탁구수영
석환401010
영재2050
인용303030
정현70070
준모100100100

테니스 대표로 준모, 탁구 대표로 인용, 수영 대표로 정현을 뽑는다면, 세 명의 각 종목에 대한 능력치의 합은 200(=100+30+70)이 됩니다.

하지만, 테니스 대표로 석환, 탁구 대표로 준모, 수영 대표로 정현을 뽑는다면 세 명의 각 종목에 대한 능력치 합은 210(=40+100+70)이 됩니다. 이 경우가 당신의 반의 각 종목 대표의 능력치 합이 최대가 되는 경우입니다.

당신의 반 학생들의 각 종목에 대한 능력치를 나타내는 2차원 정수 배열 ability가 주어졌을 때, 선발된 대표들의 해당 종목에 대한 능력치 합의 최대값을 return 하는 solution 함수를 완성하시오.

🏄🏾‍♂️ 솔루션

제한사항이 10 by 10이다. 그렇게 되면 최악의 케이스에서 10! 만큼의 연산이 필요하고 이는 3,628,800 으로 완전 탐색이 가능하다.

  • DFS를 통해 처리해야 좋을 것 같다.
    • BFS로 처리를 할 때 이미 선택된 학생을 체크하는 부분에서 시간복잡도가 증가한다.
    • 얼마나 증가하냐? 최악의 경우 10 * 10 을 곱해야 한다 (모든 학생 점수 체크 * 특정 종목에 해당 학생 배치 가능한지 경우의 수)
    • 그렇게 되면 전체 연산이 3억을 넘어가게 되므로 시간초과가 난다.
  • python의 permutations 를 써도 된다.
    • 이 부분은 개인적으로 지양하는데 내부 메소드에 의존하면 기본적 코드 실력이 떨어지는 것 같다.

코드

def dfs(ability, score, col):
    global answer, people, sports, visited

    if col== sports:
        answer = max(score, answer)
        return

    for p in range(people):
        if visited[p]:
            continue
        visited[p] = True
        dfs(ability, score+ability[p][col], col+1)
        visited[p] = False

def solution(ability):
    global answer, people, sports, visited
    answer, people, sports = 0, len(ability), len(ability[0])
    visited = [False for _ in range(people)]

    dfs(ability, 0, 0)
    
    return answer

🏐 분석 및 후기

  • 시간복잡도 : 앞서 말했듯 최악의 경우 10! 만큼의 연산 / 수식으로 표현하면
    • n = 스포츠 종목
    • m = 사람 수
    • Complexity = O(m!) / n에 따라 작아지지만 Big-O 표기법 사용
  • 공간복잡도 : O(m) - visited 체크용

앞서 BFS로 풀지 말아야 할 이유를 길게 설명했는데 그 이유는 내가 BFS로 풀었기 때문이다. 당연히 시간초과가 떴다.

DFS 써야 하는 류의 문제들을 익히자~!