📝문제 설명
📢입출력 예시
✏️문제 풀이
우선 N 값마다 만들 수 있는 팀의 경우의 수를 생각해보자
N = 4 인 경우 N = 6인 경우
(0, 1) VS (2, 3) (0, 1, 2) VS (3, 4, 5)
(0, 2) VS (3, 4) (0, 1, 3) VS (2, 4, 5)
(0, 3) VS (1, 2) (0, 1, 4) VS (2, 3, 5)
(0, 1, 5) VS (2, 3, 4)
(0, 2, 3) VS (1, 4, 5)
(0, 2, 4) VS (1, 3, 5)
(0, 2, 5) VS (1, 3, 4)
(0, 3, 4) VS (1, 2, 5)
(0, 3, 5) VS (1, 2, 4)
(0, 4, 5) VS (1, 2, 3)
경우의 수를 나열하면 0을 포함한 나머지 경우의 수만 구하면 된다.
그리고 팀 효과를 계산하기 위해서는
N = 4일 때는 (0,1)의 값만 계산하면 되지만
N = 6일 때는 (0, 1, 2)의 팀이 만들어지므로 (0,1) + (0,2) + (1,2) + (1,0) + (2,0) + (2,1) 이렇게 6번 더해주면 된다.
단 (1,0), (2,0), (2,1)는 (0,1) (0,2) (1,2)를 거꾸로 배열한거기 때문에 더할 때는 완전탐색으로 더해준다.
즉 S[i][j] + S[j][i] 를 해줘야 한다는 의미이다.
그렇다면 해야될 것은
1. 팀 구성하기
2. 구성한 팀의 효과 계산
3. 효과 계산 후 최소값 최신화 하기
1번은 백트래킹의 기초인 N과 M의 문제와 유사하고
2,3번은 팀이 구성되면 계산만 해주는 로직만 구현하면 된다.
이때 한가지 고민했던 것이 팀을 구성은 어떻게 해야될 것인가? 어떤 자료형을 사용해야되나?
N = 6일 때는 어떻게 팀 효과를 계산해줘야 하나?
(0, 1, 2)를 선택해야 한다면 위에서 생각한 것 처럼 (0,1) + (0,2) + (1,2)를 더해주면 된다고 했다.
그러면 한번에 3개를 구하는 것보다는 2개씩 구해 따로 더해주면 될 것이다.
그리고 팀을 선택했다는 것을 나타내기 위해서는 visited 방문 배열을 사용하여 팀 선택되었다면 T, 안되었다면 F를 사용하였다.
package Baekjoon.BackTracking;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Baek14889 {
static int N;
static boolean[] visited;
static int[][] synergy;
static int minScore = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer;
N = Integer.parseInt(bufferedReader.readLine());
visited = new boolean[N];
synergy = new int[N][N];
for(int i=0; i<N; i++){
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
for(int j=0; j<N; j++){
synergy[i][j] = Integer.parseInt(stringTokenizer.nextToken());
}
}
backTracking(0,0);
System.out.println(minScore);
}
private static void backTracking(int start, int depth){
if(depth == N/2){
cal();
return;
}
for(int i=start; i<N; i++){
if(!visited[i]) {
visited[i] = true;
backTracking(i+1,depth + 1);
visited[i] = false;
}
}
}
private static void cal(){
int start = 0;
int link = 0;
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
if(visited[i] && visited[j]){
start += synergy[i][j];
}else if(!visited[i] && !visited[j]){
link += synergy[i][j];
}
}
}
int min = Math.abs(start - link);
minScore = Math.min(min, minScore);
}
}
💡새로 알게된 점
'📖Algorithm > BackTracking' 카테고리의 다른 글
JAVA [Algorithm] - 백준 14888 연산자 끼워 넣기 (0) | 2025.01.08 |
---|---|
JAVA [Algorithm] - 백준 9663 N-Queen (0) | 2025.01.07 |
JAVA [Algorithm] - 백준 15650 N과 M (2) (0) | 2025.01.06 |
JAVA [Algorithm] - 백준 15649 N과 M (1) (0) | 2025.01.06 |