생각
예제에서는 N=4이고 한 팀당 2명이기 때문에 (1,2)이 한팀이고 (3,4)이 나머지 팀일때 능력치의 차이를 (S12+S21), (S34+S43)의 차이로 구했습니다. 만약 한 팀당 인원이 3명이상일땐, 예를 들어 (1,2,3)인 경우일때 팀의 능력치의 차이를 계산할땐 (S12 + S21 + S13 + S31 + S23 + S32) 와 같이 계산해줘야 합니다.
N개를 N/2로 각각 두 팀으로 나눕니다. 나눌수있는 모든 가능한 경우를 조합으로 뽑았습니다.
teamA와 teamB 정수형 배열을 만든다음 teamA에서 N/2만큼 조합으로 뽑았습니다. 그 다음으로 teamA에서 뽑히지 않은 번호들만 체크하여 teamB에 넣었습니다. (선택된 원소를 제외한 나머지 원소를 추출하는 더 좋은 방법이 있을것 같은데 일단 이렇게 구현했습니다..ㅎㅎ 스터디 때 다른 친구들은 어떻게 구현했는지 배워야겠습니다!!)
이제 각 팀의 능력치의 차이를 계산해야 합니다!
이중포문을 사용하여 가능한 팀에 속한 각각의 쌍이 map[i][j]일때 map[j][i]를 더해줬습니다. 이렇게 구한 각 팀의 능력치 차이가 최소가 되는 값을 찾아 출력해주면 됩니다.
Java code
package com.java.algorithm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Baekjoon_14889_스타트와링크 {
/**
* N개중 N/2명 조합으로 뽑는다.
* 최소값 가장 작은거 출력
* @throws IOException
* @throws NumberFormatException
* */
static int N;
static int[][] map;
static int[] teamA;
static int[] teamB;
static int ans = Integer.MAX_VALUE;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new int[N][N];
teamA = new int[N/2];
teamB = new int[N/2];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
comb(0, 0, N/2); // 두팀으로 나누기 -> teamA, teamB 정해짐
System.out.println(ans);
}
private static void comb(int cnt, int start, int total) {
if(cnt == total) {
boolean[] isSelected = new boolean[N];
for (int i = 0; i < N/2; i++) {
isSelected[teamA[i]] = true;
}
int j=0;
for (int i = 0; i < N; i++) {
if(!isSelected[i]) {
teamB[j++] = i;
}
}
int sum_a=0, sum_b=0;
for (int i = 0; i < N/2; i++) {
for (int k = i+1; k < N/2; k++) {
if(i==k) continue;
sum_a += map[teamA[i]][teamA[k]];
sum_a += map[teamA[k]][teamA[i]];
sum_b += map[teamB[i]][teamB[k]];
sum_b += map[teamB[k]][teamB[i]];
}
}
ans = Math.min(ans, Math.abs(sum_a-sum_b));
return;
}
for (int i = start; i < N; ++i) {
teamA[cnt] = i;
comb(cnt+1, i+1, total);
}
}
}
'Algorithm' 카테고리의 다른 글
[백준] Python - 1713.후보 추천하기 (0) | 2021.03.06 |
---|---|
[백준] JAVA - 1920.수 찾기 (0) | 2021.03.06 |
[백준] JAVA - 1339.단어 수학 (0) | 2021.03.01 |
[백준] JAVA - 1620.나는야 포켓몬 마스터 이다솜 (0) | 2021.03.01 |
[백준] JAVA - 18429.근손실 (0) | 2021.02.28 |