-
[BOJ] 스타트와 링크Algorithm/BOJ 2020. 2. 5. 14:14
[14889] 스타트와 링크
https://www.acmicpc.net/problem/14889
- N명을 N/2명씩 두 팀으로 나누려고 한다. (4 <= N <= 20, N은 짝수)
- 두 팀의 능력치를 구한 다음, 차이의 최소값을 구하는 문제
- S[i][j] = i 번 사람과 j 번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치
- 팀의 능력치 : 팀에 속한 모든 쌍의 S[i][j] 집합
Solution
- 순열을 사용한 완전탐색
- a[] 배열에 0을 N/2개, 1을 N/2개 넣어서 모든 순열을 구하는 것으로 다 해볼 수 있다.
- 0이면 스타트 팀, 1이면 링크 팀
- 0 아니면 1의 조합이기 때문에 모든 순열을 구하면 같은 순열을 두 번 계산하는 것과 같아서 a[0]이 1이 되면 do-while문을 종료한다.
소스코드
import java.util.Scanner; public class Main { public void go() { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] s = new int[n][n]; int[] a = new int[n]; int[] start = new int[n / 2]; int[] link = new int[n / 2]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { s[i][j] = sc.nextInt(); } } for (int i = n / 2; i < a.length; i++) { a[i] = 1; } int answer = Integer.MAX_VALUE; int ps, pl; do { if(a[0] == 1) break; int idx = 0; for (int i = 0; i < n; i++) { if (a[i] == 0) { start[idx++] = i; } } idx = 0; for (int i = 0; i < n; i++) { if (a[i] == 1) { link[idx++] = i; } } ps = 0; pl = 0; ps = calc(s, start); pl = calc(s, link); answer = Math.min(answer, Math.abs(ps - pl)); } while (next_permutation(a, n)); System.out.println(answer); } public int calc(int[][] s, int[] team) { // 각 팀의 능력치 합 계산 int sum = 0; for (int i = 0; i < team.length - 1; i++) { for (int j = i + 1; j < team.length; j++) { sum += s[team[i]][team[j]]; sum += s[team[j]][team[i]]; } } return sum; } public boolean next_permutation(int[] a, int n) { // 다음 순열 int i = n - 1; while (i > 0 && a[i - 1] >= a[i]) i -= 1; if (i <= 0) return false; int j = n - 1; while (a[i - 1] >= a[j]) j -= 1; swap(a, i - 1, j); j = n - 1; while (i < j) { swap(a, i, j); i += 1; j -= 1; } return true; } public void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } public void print(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } public static void main(String[] args) { Main main = new Main(); main.go(); } }
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ] 숨바꼭질 4 (0) 2020.02.06 [BOJ] 숨바꼭질 3 (0) 2020.02.05 [BOJ] 단어 수학 (0) 2020.02.04 [BOJ] 리모컨 (0) 2020.02.04 [BOJ] 로또 (0) 2020.02.03