https://www.acmicpc.net/problem/2098
2098번: 외판원 순회
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 16) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j
www.acmicpc.net
🔶 풀이
불특정한 도시 A에서 출발해서 한 바퀴를 돌고 도시 A로 다시 돌아왔을 때 최소 비용을 구하는 문제.
시간 제한이 적기 때문에 dp와 비트마스크를 활용해야함.
비트마스크(Bit Mask) 알고리즘 장점 및 연산자 사용 방법
비트마스크(BitMask)는 이진수를 사용하는 컴퓨터의 연산 방식을 이용하여 정수의 이진수 표현을 자료 구조로 쓰는 기법 ✅ 이진수 0 또는 1을 이용하므로 하나의 비트(Bit)가 표현할 수 있는 경우
sookr5416.tistory.com
위에서 말했듯이 외판원 순회는 싸이클 형태를 가지고 있다.
때문에 출발 도시는 원하는 곳으로 설정해주면 된다.
dp 2차원 배열로 현재 위치한 도시와 비트마스크로 방문 여부를 확인한다.
dp[현재 방문한 도시][도시 방문 여부]
dp[1][0001] 현재 위치한 도시는 1번, 여태까지 방문한 도시는 1번 도시일 때 최소 비용
dp[2][0011] 현재 위치한 도시는 2번, 여태까지 방문한 도시는 1, 2번 도시일 때 최소 비용
dp[4][1111] 현재 위치한 도시는 4번, 여태까지 방문한 도시는 1, 2, 3, 4번 도시일 때 최소 비용
✅ 주의
모든 도시를 방문했을 때 시작 도시로 갈 수 없는 경우 나올 수 없을 정도의 큰 값(INF)으로 대체
: return을 시켜버리면 추후에 방문하는 상황이 생김 → 시간 초과
초기에 dp 배열을 -1로 초기화해주고, 방문했을 때 값이 없으면 INF 값으로 변경
: 처음부터 INF 값으로 초기화 → 시간 초과
초기에 초기화했던 -1로 진행 → Math.min() 과정을 진행할 수 없음.
<최종코드>
import java.io.*;
import java.util.*;
public class Main {
static int N, map[][], dp[][];
static final int INF = 11000000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
map = new int[N][N];
dp = new int[N][1 << N];
for (int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for (int j=0; j<N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
Arrays.fill(dp[i], -1);
}
System.out.println(find(0, 1));
}
/**
*
* @param cur 현재 도착한 도시
* @param pos 현재 방문한 도시 상태값
* @return
*/
public static int find (int cur, int pos) {
// 전부 방문한 경우
if (pos == (1 << N) -1) {
if (map[cur][0] == 0) return INF;
return map[cur][0];
}
// dp 값이 존재하는 경우
if (dp[cur][pos] != -1) return dp[cur][pos];
dp[cur][pos] = INF;
for (int i=0; i<N; i++) {
// 길이 있고, 방문하지 않은 경우
if ((pos & (1 << i)) == 0 && map[cur][i] != 0) {
int next = (pos | (1 << i));
dp[cur][pos] = Math.min(dp[cur][pos], find(i, next) + map[cur][i]);
}
}
return dp[cur][pos];
}
}
'알고리즘 > 다이나믹 프로그래밍(DP)' 카테고리의 다른 글
[자바로 푸는 백준] 2618번 경찰차 (0) | 2023.05.15 |
---|---|
[자바로 푸는 백준] 11570번 환상의 듀엣 (1) | 2023.05.12 |
[백준]JAVA - 1102번: 발전소 (0) | 2023.04.15 |
[백준]JAVA - 1028번: 다이아몬드 광산 (0) | 2023.04.14 |
[백준]JAVA - 1915번: 가장 큰 정사각형 (0) | 2023.04.11 |