[白俊]外審員巡り
12213 ワード
外审员巡回
コード#コード# n = int(input())
inf = float('inf')
data = [list(map(int, input().split())) for _ in range(n)]
dp = [[inf for _ in range(1 << n)] for _ in range(n)]
def dfs(x, visited): # x : 현재 방문한 노드, visited : 지금까지 방문 노드를 담고있는 기록
if dp[x][visited] != inf: # 겪은 상황일 경우
return dp[x][visited]
if visited == (1 << n) - 1: # 모든 노드를 방문한 경우
if data[x][first] != 0: # 다시 최초 출발지로 돌아가야 한다. x -> first
return data[x][first]
else:
return inf
min_val = inf
for to in range(n): # 전체 노드 방문
if to == first: # 최초 출발지는 제외
continue
if data[x][to] == 0: # x->to의 길이 없는 경우 제외
continue
if visited & (1 << to) != 0: # 방문기록에 존재하는 지점(to)은 제외
continue
min_val = min(min_val, data[x][to] + dfs2(to, visited | (1 << to)))
dp[x][visited] = min_val
return min_val
first = 2 # 최초 출발지 0 ~ n-1 중 임의의 노드를 선택 (무엇을 선택해도 결과는 같다)
print(dfs(first, 2 ** first))
方法
n = int(input())
inf = float('inf')
data = [list(map(int, input().split())) for _ in range(n)]
dp = [[inf for _ in range(1 << n)] for _ in range(n)]
def dfs(x, visited): # x : 현재 방문한 노드, visited : 지금까지 방문 노드를 담고있는 기록
if dp[x][visited] != inf: # 겪은 상황일 경우
return dp[x][visited]
if visited == (1 << n) - 1: # 모든 노드를 방문한 경우
if data[x][first] != 0: # 다시 최초 출발지로 돌아가야 한다. x -> first
return data[x][first]
else:
return inf
min_val = inf
for to in range(n): # 전체 노드 방문
if to == first: # 최초 출발지는 제외
continue
if data[x][to] == 0: # x->to의 길이 없는 경우 제외
continue
if visited & (1 << to) != 0: # 방문기록에 존재하는 지점(to)은 제외
continue
min_val = min(min_val, data[x][to] + dfs2(to, visited | (1 << to)))
dp[x][visited] = min_val
return min_val
first = 2 # 최초 출발지 0 ~ n-1 중 임의의 노드를 선택 (무엇을 선택해도 결과는 같다)
print(dfs(first, 2 ** first))
方法
dp[0][011]の意味
0
0111
です.(0111は2進数、10進数で7)0111
^3번 노드의 방문 여부를 나타낸다. (0이므로 아직 방문하지 않은 상태)
0111
^2번 노드의 방문 여부를 나타낸다. (1이므로 방문한 상태)
0111
^1번 노드의 방문 여부를 나타낸다. (1이므로 방문한 상태)
0111
^0번 노드의 방문 여부를 나타낸다. (1이므로 방문한 상태)
dp[0][0111] (== dp[0][7])
►現在のアクセスノードが0、アクセスレコードが0111(7)の場合、すべての場合のコストが最も低くなります.まず、現在のアクセスノードは0、アクセスレコードは0111
これは,以前にアクセスしたノードが1,2であることを意味する.
この場合、可能な経路は
1->2->0
または2->1->0
である.上記可能な経路のうち、最も費用のかかる経路は
dp[0][0111]
に記録される.dp[0][011]注釈されるプロセス
...
def dfs(x, visited):
# 현재 방문한 노드는 x, 현재까지 방문기록은 visited이다.
...
min_val = inf
for to in range(n): # 전체 노드 방문
...
# for 문에서 방문이 가능한 노드들을 고른다.
# "x(현재노드) -> to(그 다음 방문노드) -> ... -> 최초 방문 노드"
# 의 비용을 나타내는 코드가
# data[x][to] + dfs2(to, visited | (1 << to) 이 부분이다.
min_val = min(min_val, data[x][to] + dfs2(to, visited | (1 << to)))
# 현재 방문한 노드는 x, 현재까지의 방문 기록이 visited인 상황에서
# 위 for문을 통해 가능한 모든 경로를 계산하여 그 중 최소 비용이 min_val 변수에 담겨있다.
# 이를 dp[x][visited]에 메모한다.
dp[x][visited] = min_val
return min_val
...
ポイントは、dp[x][visited]
がすべての可能な経路計算後の最低費用を含んでいることです.ビットマスクによる集約演算
Reference
この問題について([白俊]外審員巡り), 我々は、より多くの情報をここで見つけました https://velog.io/@guswns3371/백준-외판원-순회テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol