티스토리 뷰

728x90

문제 링크

www.acmicpc.net/problem/2098

 

2098번: 외판원 순회

첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 16) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j

www.acmicpc.net

 

풀이

1) 어떤 정점에서 시작하든 최소 비용은 같습니다. 그러니 0번부터 조집시다.

A->B->...->F->A

B->C->...->A->B

모두 같습니다.

 

2) 현재까지 어느 정점들을 탐색해왔는지 비트 마스킹으로 관리합니다. 그 집합과 현재 정점을 기준으로 dp를 전개합니다. 다음으로 이동할 정점을 고를 때 집합에 포함되지 않는 정점을 고르면 됩니다.

 

3) 기저 사례는 $(n-1)$번까지의 모든 비트가 1인 경우입니다. 이때 마지막 정점에서 0번 정점으로 갈 수 있는지를 확인해 적절한 값을 리턴해줍시다.

 

 

정답 코드

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
using namespace std;

int d[1 << 17][22];
int p[22][22], n;

int go(int s, int now) {
    if (s == ((1 << n) - 1)) {
        return p[now][0]? p[now][0] : INF;
    }
    int &ret = d[s][now];
    if (ret != -1) return ret;
    ret = INF;
    for (int next = 1; next < n; next++) {
        if (s & (1 << next)) continue;
        if (p[now][next] == 0) continue;
        ret = min(ret, go(s | (1 << next), next) + p[now][next]);
    }
    return ret;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    memset(d, -1, sizeof(d));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> p[i][j];
        }
    }
    cout << go(1, 0);
}
728x90

'알고리즘 > 문제 풀이' 카테고리의 다른 글

[BOJ] 백준 2887 행성 터널  (0) 2021.03.08
[BOJ] 백준 2623 음악프로그램  (0) 2021.03.08
[BOJ] 백준 2342 Dance Dance Revolution  (0) 2021.03.08
[BOJ] 백준 2252 줄 세우기  (0) 2021.03.08
[BOJ] 백준 2239 스도쿠  (0) 2021.03.08
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함