N x N 격자에 각 i 번호의 선수와 j 번호의 선수가 같은 팀 일때의 점수를 표기하고, 두 팀의 점수차가 최소가 되게 팀을 구성했을 때의 최소값을 출력하는 문제이다.
N의 수가 최대 20이라서 최악의 경우가 20명중에 10명뽑는 경우의 수가 된다. `20 C 10 = 184756` 이므로 브루트포스와 백트래킹을 쓰면 풀릴 것 같았다.
더보기
더보기
import java.io.*;
import java.util.*;
import java.util.List;
public class Main {
public static int ans, N;
public static int[][] MAP;
public static boolean[] chk;
public static void InputData() {
try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
N = Integer.parseInt(stk.nextToken());
MAP = new int[N][N];
chk = new boolean[N];
ans = Integer.MAX_VALUE;
for(int i = 0; i < N; i++){
stk = new StringTokenizer(br.readLine(), " ");
for(int j = 0; j < N; j++){
MAP[i][j] = Integer.parseInt(stk.nextToken());
}
}// N^2
}catch (IOException e){
e.printStackTrace();
}
} // 데이터 입력
public static void Print_result(){
try(BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))){
bw.write(String.valueOf(ans));
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
} // 결과 출력
public static void solve(int ceil, int cnt, int idx){
if(ceil == cnt){
int A = 0, B = 0;
for(int i = 0; i < N; i++){
for(int j = i + 1; j < N; j++) {
if(chk[i] && chk[j]){
A += MAP[i][j] + MAP[j][i];
}else if(!chk[i] && !chk[j]){
B += MAP[i][j] + MAP[j][i];
}
}
}
ans = Math.min(ans, Math.abs(A-B));
return;
}
for(int i = idx; i < N; i++){
if(chk[i])
continue;
chk[i] = true;
solve(ceil, cnt + 1, i);
chk[i] = false;
}
}
public static void main(String[] args){
InputData();
solve(N/2, 0, 0);
Print_result();
}
}