반응형
문제 출처 :
https://www.acmicpc.net/problem/14889
알고리즘 분석 :
문제 해결에 필요한 사항
1. 백트래킹
백트래킹으로 문제를 해결해보자.
우선 이 문제를 해결하기전에 스타트와 링크를 나누는 법에 대해 생각해보자.
어떤 그룹에 1 2 3 4 5 6 7 8이 있다면
반으로 나누면 각각이 1팀 2팀이 만들어진다.
즉, 1 2 3 4와 5 6 7 8로 나누거나
1 2 3 5와 4 6 7 8로 나누는 방법들이다.
따라서 우리는 만들어질 수 있는 조합을 백트래킹으로 이용하여 앞 n / 2부분을 스타트팀으로 만들고 뒤 n / 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 | #include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <map> using namespace std; int arr[22][22]; int n; int ans = 987654213; void dfs(int now, vector<int> vc, int cnt) { if (cnt == n / 2) { vector<int> lvc; bool visit[22] = { 0, }; for (int i = 0; i < vc.size(); i++) visit[vc[i]] = true; for (int i = 0; i < n; i++) if (!visit[i]) lvc.push_back(i); int start = 0; for (int i = 0; i < vc.size(); i++) for (int j = i + 1; j < vc.size(); j++) start += (arr[vc[i]][vc[j]] + arr[vc[j]][vc[i]]); int link = 0; for (int i = 0; i < lvc.size() - 1; i++) for (int j = i + 1; j < lvc.size(); j++) link += (arr[lvc[i]][lvc[j]] + arr[lvc[j]][lvc[i]]); ans = min(ans, abs(start - link)); return; } for (int i = now; i < n; i++) { vc.push_back(i); dfs(i + 1, vc, cnt + 1); vc.pop_back(); } return; } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) scanf("%d", &arr[i][j]); vector<int> v; dfs(0, v, 0); printf("%d", ans); return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
반응형
'Applied > 알고리즘 문제풀이' 카테고리의 다른 글
[11663번] 선분 위의 점 (0) | 2018.04.19 |
---|---|
[2567번] 색종이1 (0) | 2018.04.16 |
[14501번] 퇴사 (0) | 2018.04.12 |
[3190번] 뱀 (0) | 2018.04.09 |
[14502번] 연구소 (0) | 2018.04.06 |