728x90

문제

 

 

접근 방식

짝수 명의 직원들을 절반씩 나누어 두 팀으로 구성할 때

두 팀의 능력치 차이가 가장 적은 경우를 구해야 한다.

 

각 팀을 모두 조합할 필요는 없고 한 팀만 구해도 되는데

한쪽팀만 구하면 반대팀은 자동으로 구성되기 때문이다.

 

백트래킹을 이용해 절반인 n/2까지 재귀를 호출하며

팀을 짜주고 n/2일 때 현재까지 기록으로

각 팀간의 점수차를 구해주면 된다.

 

즉, 절반의 팀을 구하는 메서드와

각 팀의 점수를 계산하고 차이를 구하는 메서드가 필요하다.

 

풀이

class Main {
    
    static int n, m;
	static int min = Integer.MAX_VALUE;
	static int[][] stats;
	static boolean[] isUsed;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;

		n = Integer.parseInt(br.readLine());
		m = n/2;

		stats = new int[n][n];
		isUsed = new boolean[n];

		for (int i = 0; i < n; i++) {
			st = new StringTokenizer(br.readLine());

			for (int j = 0; j < n; j++) {
				stats[i][j] = Integer.parseInt(st.nextToken());
			}
		}

		solve(0, 0);

		System.out.println(min);
	}

	static void solve(int s, int start) {
		if (s == m) {
			calculate();
			return;
		}

		for (int i = start; i < n; i++) {
			if (isUsed[i]) continue;
			if (s == 0 && i > 0) break;
			isUsed[i] = true;
			solve(s + 1, i + 1);
			isUsed[i] = false;
		}
	}

	static void calculate() {
		int start = 0;
		int link = 0;

		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				if (isUsed[i] == isUsed[j]) {
					if (isUsed[i]) {
						start += (stats[i][j] + stats[j][i]);
					} else {
						link += (stats[i][j] + stats[j][i]);
					}
				}
			}
		}

		min = Math.min(min, Math.abs(start - link));
	}
}

 

'Java > Algorithms' 카테고리의 다른 글

[백준] 12100번 : 2048 (Easy)  (0) 2024.03.30
[백준] 14502번 : 연구소  (1) 2024.03.29
[백준] 14888번 : 연산자 끼워넣기  (0) 2024.03.28
[백준] 1966번 : 프린터 큐  (0) 2024.03.27
[백준] 6593번 : 상범 빌딩  (0) 2024.03.25

+ Recent posts