1. 백트래킹을 통해 n/2 개 고르는 모든 경우에 대해 탐색한다.
2. n/2 개 고를때마다 시너지값을 구해 차를 구한다.
3. 반복하여 최소값을 찾는다.
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 | #include <iostream> #include <vector> #include <algorithm> using namespace std; int t, n, res; int map[16][16]; bool visited[16]; // 시너지 계산하기 int calc(vector<int> &v) { int ans = 0; for (int i = 0; i < n/2; i++) { for (int j = 0; j < n/2; j++) { if (i == j)continue; ans += map[v[i]][v[j]]; } } return ans; } int getResult() { vector<int> a; // 선택된 팀 vector<int> b; // 선택되지 않은 팀 for (int i = 0; i < n; i++) { if (visited[i]) a.push_back(i); else b.push_back(i); } //시너지의 차 구하기 return abs(calc(a) - calc(b)); } //백트래킹 void dfs(int v, int cnt) { visited[v] = true; if (cnt == n/2) { res = min(res, getResult()); } else { for (int i = v + 1; i < n; i++) { dfs(i, cnt + 1); } } visited[v] = false; } int main() { ios_base::sync_with_stdio(false); cin >> t; for (int tc = 1; tc <= t; tc++) { cin >> n; res = 1e9; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> map[i][j]; } } dfs(0, 1); cout << "#" << tc << " " << res << "\n"; } } | cs |
'SWEA::문제풀이' 카테고리의 다른 글
4013 특이한 자석 (0) | 2018.03.26 |
---|---|
4008 숫자 만들기 (0) | 2018.03.22 |
1258 행렬찾기 (0) | 2018.02.25 |
1252 하나로 (0) | 2018.02.25 |
3143 가장 빠른 문자열 타이핑 (0) | 2018.02.24 |