2098번: 외판원 순회
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 16) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j
www.acmicpc.net
DP 테크닉중 하나이다.
여기서 팁은
1->......->1
2->.....->2
시작점이 어디던 시작점 -> 시작점으로 왔을때의 최솟값은 다 똑같다.
그래서 걍 1부터 시작해도 된다.
dp[][]을 생각하는게 여간 쉽지 않다. 복습이 많이 필요하다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
import java.util.*;
import java.io.*;
import java.math.*;
public class D210407_boj2098_외판원순회 {
static int n;
static final int INF = 987654321;
static int arr[][];
static int d[][];
/* 제일 중요함!!!!!!!!
d[node][visit] :
현재 node번에 있고 visit을 방문하고 왔을때 0번 노드로 가는 최소의 거리
visit은 비트마스크이다.
d[0][1] == 현재 0번 노드에 있고 0번 노드만 방문 하고 있는 상태일때 0번노드로 가는 최소의 거리.
d[2][5] == 현재 2번 노드에 있고 0,2번 노드를 방문하고 있는 상태일때 0번 노드로 가는 최소의 거리.
*/
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
arr = new int[n][n];
d = new int[n][(1<<n)];
for(int i = 0 ; i < n ; i++) {
}
for(int i = 0 ; i < n ; i++) {
Arrays.fill(d[i], INF);
StringTokenizer st = new StringTokenizer(br.readLine());
for(int j = 0 ; j < n ; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
//go(0,1) == d[0][1] => 16번째 줄을 보면 된다.
System.out.println(go(0,1));
}
static int go(int cur_node, int visit) {
if(visit == (1<<n)-1) {
if(arr[cur_node][0] == 0)
return INF;
else
return arr[cur_node][0];
}
if(d[cur_node][visit] != INF)
return d[cur_node][visit];
for(int i = 0 ; i < n ; i++) {
//cur_node -> i 에 대한 길이 없다 || 이미 방문한 노드이면??
if(arr[cur_node][i] == 0 || (visit & (1 << i)) != 0)
continue;
int n_visit = visit | (1<< i);
//만약 2번 노드를 다음것으로 쓰려면 arr[cur_node][2] + d[i][visit | (1<<2)];
d[cur_node][visit] = Math.min(d[cur_node][visit], arr[cur_node][i] + go(i, n_visit));
}
return d[cur_node][visit];
}
}
|
cs |
그런데
jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=817&sca=5050
JUNGOL
www.jungol.co.kr
이 문제 때문에 java일 경우 탑다운이 안먹히는 경우가 있었다.
그래서 바텀업도 만들었다. (근데 당장에는 익히진 않을 것이다. 왜냐면 짜기 너무 어려움;;;;)
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import java.util.*; import java.io.*; import java.math.*; public class D210407_jungol1545_해밀턴순환회로2_bottomup { static int n; static final int INF = 987654321; static int arr[][]; static int d[][]; public static void main(String[] args) throws IOException { //System.setIn(new FileInputStream("input.txt")); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); n = Integer.parseInt(br.readLine()); arr = new int[n][n]; d = new int[n][(1<<n)]; for(int i = 0 ; i < n ; i++) { Arrays.fill(d[i], INF); StringTokenizer st = new StringTokenizer(br.readLine()); for(int j = 0 ; j < n ; j++) { arr[i][j] = Integer.parseInt(st.nextToken()); if(i != j && arr[i][j] == 0) arr[i][j] = INF; } } //d[0][1<<19 -1] 마지막이 0번노드이고 모든 정점을 방문했을때 //d[0][1] 마지막이 0번노드이고 0번노드만 방문했을때 = 0 //d[1][3] 마지막이 1번노드이고 0,1번 노드 방문했을때 = arr[0][1]; //d[3][9] 마지막이 3번노드이고 0,3번 노드 방문했을때 = arr[0][3]; d[0][1] = 0; for(int i = 1 ; i < n ; i++) { d[i][(1<<i) + 1] = arr[0][i]; } // d[j][i] 에서 i는 0번노드는 무조건 방문상태여야 한다. 당연히 0번부터 시작했으니깐... 그래서 1 부터 +2를 하는 방식을 취했다. for(int i = 1 ; i < (1<<n)-1 ; i+=2) { // i는 visit. bitmask 전체를 훑는다. for(int j = 1 ; j < n ; j++) { // j 중간 경유 노드이다. 그런데 j = 0는 빼도 된다. 왜냐면 0번 노드는 이미 방문했으니깐... for(int k = 1 ; k < n ; k++) { // k는 마지막 방문 노드이다. 그런데 k = 0 는 빼도 된다. 왜냐면 0번 노드는 이미 방문했으니깐... if((i & (1<<k)) != 0) continue; d[k][i+(1<<k)] = Math.min(d[k][i+(1<<k)], d[j][i] + arr[j][k]); } } } int ans = INF; for(int i = 1 ; i < n ; i++) ans = Math.min(ans, d[i][(1<<n) -1] + arr[i][0]); System.out.println(ans); } } /* 5 0 14 4 10 20 14 0 7 8 7 4 5 0 7 16 11 7 9 0 2 18 7 17 4 0 */ | cs |
'알고리즘 기술' 카테고리의 다른 글
Convex Hull (0) | 2021.04.21 |
---|---|
[DP] LIS, LCS, MCM (0) | 2021.04.09 |
LCA (0) | 2020.08.20 |
위상정렬 Feat DFS, BFS (0) | 2020.08.20 |
Trie와 동적 Trie (0) | 2020.08.19 |