반응형
2098번 외판원 순회
1. 이해하기
- 비트마스크와 DP를 이용하는 문제이다.
- 비트마스크를 이용하여 방문한 지점을 체크하고 DP를 이용하여 특정 지점까지의 최소거리를 갱신한다.
2. 구현하기
-
TSP(current,visited)일때 방문한 지점은 visited & (1<<next) 로 확인할 수 있다.
- 기저사례: visited가 (1<<N)-1과 같으면 모든 지점을 방문한 상태이다. 이때 처음지점으로 돌아갈 수 있는지 확인해서 돌아갈 수 있으면 그때의 cost를, 없으면 INF값을 줘야한다.
- 다음으로 방문할 지점을 체크해서 갈 수 있으면 간다.
- 시작지점은 어떤 점으로 설정해도 값은 같기 때문에 0에서 시작한다고 생각한다.
int TSP(int current, int visited) { if(visited == (1<<N)-1) return (cost[current][0])?cost[current][0]:INF; int& ret = cache[current][visited]; if(ret != -1) return ret; ret = INF; for(int i = 0; i < N; i++) { if(visited & (1<<i)) continue; if(cost[current][i] == 0) continue; ret = min(ret,TSP(i,visited | (1<<i))+cost[current][i]); } return ret; }
3. 전체코드
#include <iostream>
#include <cstring>
using namespace std;
int N,cost[16][16],cache[16][(1<<16)];
const int INF = 987654321;
int TSP(int current, int visited) {
if(visited == (1<<N)-1)
return (cost[current][0])?cost[current][0]:INF;
int& ret = cache[current][visited];
if(ret != -1) return ret;
ret = INF;
for(int i = 0; i < N; i++) {
if(visited & (1<<i)) continue;
if(cost[current][i] == 0) continue;
ret = min(ret,TSP(i,visited | (1<<i))+cost[current][i]);
}
return ret;
}
int main() {
cin >> N;
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
cin >> cost[i][j];
memset(cache,-1,sizeof(cache));
cout << TSP(0,1) << '\n';
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 10815번 숫자 카드 (0) | 2019.12.11 |
---|---|
[백준] 2873번 롤러코스터 (0) | 2019.12.11 |
[백준] 1967번 트리의 지름 (0) | 2019.11.06 |
[백준] 17822번 원판 돌리기 (0) | 2019.10.24 |
[백준] 17142번 연구소 3 (0) | 2019.10.14 |