For Programmer

백준 1311번 파이썬 문제풀이(할 일 정하기 ) - (dp + 비트마스킹) 본문

코팅테스트/백준 문제 모음

백준 1311번 파이썬 문제풀이(할 일 정하기 ) - (dp + 비트마스킹)

유지광이 2022. 4. 14. 00:51
728x90


'''
| 특정 비트를 킬때 사용 ( x |= (1 << 2))
& 특정비트가 켜져있는지 혹은 특정 비트를 끌 때 사용 (x & (1 << 2)) != 0 or (x & ~(1 << 2)
^ 특정 비트 상태를 반전시킬 때 사용 (x ^ (1 << 2))
tip) x & (-x) x의 제일 오른쪽 1이 나온다.
'''
import sys

input = sys.stdin.readline


def dfs(row, visit):
    if row == N:
        return 0

    if visited[row][visit] != -1:
        return visited[row][visit]

    ret = 1000000000
    for i in range(N):
        if (visit & (1 << i)) != 0:  # 특정 비트가 켜저있다면
            continue

        ret = min(ret, dfs(row + 1, (visit | (1 << i))) + tasks[row][i])

    visited[row][visit] = ret

    return visited[row][visit]


N = int(input())
tasks = [list(map(int, input().split())) for _ in range(N)]

visited = [[-1] * (1 << N) for _ in range(N)]
print(dfs(0, 0))

-> 위와 같이 2차원 방문처리로 풀어도 되고 시간복잡도를 더줄이고 싶다면 아래와 같이 1차원 방문처리로 풀어도 상관없다.

 


import sys

input = sys.stdin.readline


def dfs(row, visit):
    if row == N:
        return 0

    if visited[visit] != -1:
        return visited[visit]

    ret = 1000000000
    for i in range(N):
        if (visit & (1 << i)) != 0:  # 특정 비트가 켜저있다면
            continue

        ret = min(ret, dfs(row + 1, (visit | (1 << i))) + tasks[row][i])
       
    visited[visit] = ret

    return visited[visit]


N = int(input())
tasks = [list(map(int, input().split())) for _ in range(N)]

visited = [-1] * (1 << N)
print(dfs(0, 0))
728x90
Comments