반응형
문제 출처 :
https://swexpertacademy.com/main/searchAll/search.do?keyword=%EC%B5%9C%EC%A0%81+%EA%B2%BD%EB%A1%9C
알고리즘 분석 :
문제 해결에 필요한 사항
1. Dynamic Programming
2. 점화식 세우는 방법
외판원 순회 문제이다. 모든 경우를 다 보는 경우, 비트마스크를 이용하는 방법 총 2가지가 있다.
시간 복잡도는 아래 코드에 기록해두었다.
소스 코드 :
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 | /* 외판원 순회 문제를 완전 탐색으로 푸는 방식이다. 시간 복잡도는 O(N!)이다. */ #include <iostream> int ABS(int a) { return a > 0 ? a : -a; } int MIN(int a, int b) { return a < b ? a : b; } struct Pt { int x, y; }; Pt pt[15]; Pt company, house; int n; int visit[15]; void init() { for (int i = 0; i < 15; i++) visit[i] = -1; } int getDist() { int ret = 0; ret += (ABS(company.x - pt[visit[0]].x) + ABS(company.y - pt[visit[0]].y)); for (int i = 1; i < n; i++) ret += (ABS(pt[visit[i - 1]].x - pt[visit[i]].x) + ABS(pt[visit[i - 1]].y - pt[visit[i]].y)); ret += (ABS(house.x - pt[visit[n - 1]].x) + ABS(house.y - pt[visit[n - 1]].y)); return ret; } int dfs(int here) { int ret = 987654321; if (here == n) return getDist(); for (int i = 0; i < n; i++) { if (visit[i] == -1) { visit[i] = here; ret = MIN(ret, dfs(here + 1)); visit[i] = -1; } } return ret; } int main() { freopen("input.txt", "r", stdin); int tCase; scanf("%d", &tCase); for (int tc = 1; tc <= tCase; tc++) { init(); scanf("%d", &n); scanf("%d %d", &company.x, &company.y); scanf("%d %d", &house.x, &house.y); for (int i = 0; i < n; i++) scanf("%d %d", &pt[i].x, &pt[i].y); printf("#%d %d\n", tc, dfs(0)); } return 0; } | cs |
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 75 76 77 78 79 | /* 외판원 순회 문제를 비트마스크로 푸는 방식이다. 총 12개의 방문가능 노드가 있기에 int형에서 비트 마스크를 통해 방문 값을 처리 할 수 있다. 공간복잡도 O(N * 2^N), 시간복잡도 O(N^2 * 2^N)가 된다. */ #include <iostream> #define INF 987654321 #define min(a,b)(a < b ? a : b) #define swap(a,b){Pt t = a; a = b; b = t;} struct Pt { int x, y; }; Pt pt[12 + 2]; int dp[12 + 2][(1 << 12) + 2]; int n; void init() { for (int i = 0; i < 14; i++) for (int j = 0; j < (1 << 12) + 2; j++) dp[i][j] = INF; } int abs(int a, int b) { return a - b > 0 ? a - b : b - a; } int getDist(Pt a, Pt b) { return abs(a.x - b.x) + abs(a.y - b.y); } int TSP(int here, int visit) { int &ret = dp[here][visit]; if (ret != INF) return ret; if (visit == ((1 << (n - 1)) - 1)) { return ret = getDist(pt[here], pt[n - 1]); } for (int i = 1; i < n - 1; i++) { if (visit & (1 << i)) continue; int dist = getDist(pt[here], pt[i]); ret = min(ret, TSP(i, visit | (1 << i)) + dist); } return ret; } int main() { //freopen("input.txt", "r", stdin); int tCase; scanf("%d", &tCase); for (int tc = 1; tc <= tCase; tc++) { init(); scanf("%d", &n); n += 2; for (int i = 0; i < n; i++) scanf("%d %d", &pt[i].x, &pt[i].y); swap(pt[1], pt[n - 1]); int ret = 987654321; int visit = (1 << 0); for (int i = 1; i < n - 1; i++) { int dist = getDist(pt[0], pt[i]); ret = min(ret, TSP(i, visit | (1 << i)) + dist); } printf("#%d %d\n", tc, ret); } return 0; } | cs |
반응형
'Applied > 알고리즘 문제풀이' 카테고리의 다른 글
[1269번] 대칭 차집합 (0) | 2019.07.02 |
---|---|
[3124번] 최소 스패닝 트리 (0) | 2019.07.01 |
[1263번] 사람 네트워크2 (0) | 2019.06.20 |
[11060번] 점프 점프 (0) | 2019.06.15 |
[1949번] 등산로 조성 (0) | 2019.06.11 |