티스토리 뷰
ㄴ
외판원 순회 문제와 비슷한 유형인데, 차이점이라면 외판원 순회 문제는 반드시 모든 노드를 방문해야 했었다면 이 문제는 방문할 필요가 없는 노드(이미 가동되어 있는 발전소)가 존재하고, 또 p값이 n보다 작을 수 있다. 이 말은 곧 모든 노드를 방문할 필요가 없다는 뜻이다.
외판원 순회 문제의 dfs함수 구조와 dp배열이 다르다. 그 이유는 모두 '현재 위치가 어디인지 상관 없기'때문이다. 외판원 순회 문제의 경우에는 현재 자신이 어느 노드에 위치해있느냐에 따라서 갈 수 있는 지점이 달라지는 반면에, 이 문제는 가동되어 있는(visited에서 1인)노드라면 어디든지 도달 가능하기 때문이다. 따라서 굳이 현재 위치를 기록할 필요가 없고 그에 따라 dfs함수와 dp배열에도 현재위치를 기록하는 부분이 없다.
그리고 또 다른 차이점은 dfs함수 내에 2중 for문이 존재한다. 출발점을 나타내는 from부분과 도착점을 나타내는 to부분이다. 이 부분을 떠올려내기가 힘들었다. 외판원 순회 문제에서는 현재 위치하고 있는 cur에서 도달 가능한 곳만 고려하는 반면에 이 문제는 그렇지 않기 때문이다. 두 문제의 유형은 비슷하지만 차이점에 따라서 세부 구현이 어떻게 달라지는지 알게되었다.
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 |
#include<stdio.h>
#define INF 1<<10
int dp[1 << 17], dist[20][20];
int n, ans,p;
int fMin(int a, int b) {
return a > b ? b : a;
}
int dfs(int cnt, int visited) {
if (cnt >= p) {
return 0;
}
if (dp[visited] != -1)
return dp[visited];
dp[visited] = INF;
for (int from = 1; from <= n; from++) {
if (visited & (1 << from)) { //가동된 발전소에서만 이동 가능
for (int to = 1; to <= n; to++) {
if (from == to) continue;
if (visited & (1 << to)) continue; //이미 가동된 발전소는 방문할 필요 없음
int next_visited = visited | (1 << to);
dp[visited] = fMin(dp[visited], dfs(cnt + 1, next_visited)+dist[from][to]);
}
}
}
return dp[visited];
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
scanf("%d ", &dist[i][j]);
}
for (int j = 0; j <= (1 << n+1); j++)
dp[j] = -1;
int init = 0, init_cnt = 0;
for (int i = 1; i <= n + 1; i++) {
char a; scanf("%c", &a);
if (a == 'Y') {
init |= (1 << i);
init_cnt++;
}
}
scanf("%d", &p);
if (init_cnt == 0 && p!=0) //초기에 가동된 발전소가 0개라 하더라도, p=0이라면 답은 0이다. *사소한 예외처리
ans = -1;
else ans = dfs(init_cnt, init);
printf("%d\n", ans);
return 0;
} |
cs |
'Problem Solving > Dynamic Programming' 카테고리의 다른 글
2624-동전 바꿔주기 (0) | 2018.12.03 |
---|---|
12865-평범한 배낭 (0) | 2018.12.03 |
2294-동전2 (0) | 2018.12.03 |
2293-동전1 (0) | 2018.12.02 |
2098-외판원 순회(Bitmask) (0) | 2018.12.02 |
댓글