● 문제
● 풀이
package backJoon.step15.백트래킹.스타트와링크;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
// 사람 수
static int N;
// 각각의 능력치를 담을 배열
static int[][] arr;
// 방문 확인
static boolean[] visited;
// 능력치 차이의 최솟값
static int MIN = Integer.MAX_VALUE;
/**
* 스타트팀과 링크팀으로 나눈 시너지 효과의 최솟값
*
* @param args
* @throws NumberFormatException
* @throws IOException :
*
* @since 2022. 8. 19. 오후 1:59:56
* @author "KyungHun Park"
*
* @modified 2022. 8. 19. 오후 1:59:56 || Kyunghun Park || 최초 생성
*
*/
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
// 사람 수 입력
N = Integer.parseInt(br.readLine());
// 사람 수 만큼 초기화
arr = new int[N][N];
visited = new boolean[N];
// 배열에 능력치 입력
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
dfs(0, 0);
System.out.println(MIN);
}
/**
* dfs를 통해 최대 방문 시 최솟값을 확인하기 위한 함수
*
* @param value : 현재 방문 위치
* @param depth : 현재 깊이
*
* @since 2022. 8. 19. 오후 2:00:46
* @author "KyungHun Park"
*
* @modified 2022. 8. 19. 오후 2:00:46 || Kyunghun Park || 최초 생성
*
*/
private static void dfs(int value, int depth) {
if (depth == N / 2) {
point();
return;
}
for (int i = value; i < N; i++) {
if (!visited[i]) {
visited[i] = true;
dfs(i + 1, depth + 1);
visited[i] = false;
}
}
}
/**
* 가장 깊은 곳 까지 방문 시 두 팀의 능력치가 최솟값인지 확인
*
*
* @since 2022. 8. 19. 오후 2:02:06
* @author "KyungHun Park"
*
* @modified 2022. 8. 19. 오후 2:02:06 || Kyunghun Park || 최초 생성
*
*/
private static void point() {
// 스타크팀 능력치 합
int teamStart = 0;
// 링크팀 능력치 합
int teamLink = 0;
// 점수의 합
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (visited[i] && visited[j]) {
teamStart += arr[i][j];
teamStart += arr[j][i];
} else if (!visited[i] && !visited[j]) {
teamLink += arr[i][j];
teamLink += arr[j][i];
}
}
}
// 스타크팀과 링크팀의 점수차를 절대값
int resPoint = Math.abs(teamStart - teamLink);
// 0인 경우보다 작은 경우는 없으니 0을 출력하고 바로 종료
if (resPoint == 0) {
System.out.println(0);
System.exit(0);
}
// 최솟값 갱신
MIN = Math.min(resPoint, MIN);
}
}