티스토리 뷰
728x90
문제
- 축구를 하기 위해 모인 사람은 총 N명
- 스타트 팀과 링크 팀으로 사람들을 나눠야 함
- 두 팀의 인원수는 같지 않아도 되지만, 한 명 이상이어야 함
- 각 사람에게 번호를 1 ~ N까지 배정하고 능력치를 조사함
- S[ij]는 i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치
- 팀의 능력치는 팀에 속한 모든 쌍의 능력치의 합
- 스타트 팀의 능력치와 링크 팀의 능력치의 차이를 최소로 하려 함
해결방법
부분집합으로 팀을 구성할 수 있는 인원들을 뽑은 뒤, 각 팀별로 능력치를 합산하고 차이를 비교해 정답을 구할 수 있도록 구성하였다.
부분집합을 구하는 코드는 아래 포스팅을 참고하면 좋을 것 같다.
코드
import java.io.*;
import java.util.*;
public class Main {
static int N, result; // 플레이어 수, 정답
static int[][] player; // 플레이어 능력치
static boolean[] visit; // 부분집합을 구하기 위한 방문처리 배열
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
player = new int[N][N];
// 플레이어 능력치 저장
for(int i = 0; i<N; i++){
StringTokenizer st = new StringTokenizer(br.readLine());
for(int j = 0; j<N; j++){
player[i][j] = Integer.parseInt(st.nextToken());
}
}
result = Integer.MAX_VALUE;
visit = new boolean[N];
solve(0);
System.out.println(result);
}
// 부분집합 찾는 함수
static void solve(int cnt){
// 부분집합 뽑았을 때,
if(cnt == N){
int start = 0;
int link = 0;
// 같은 팀원들끼리 능력치 합산
for(int i = 0; i<N; i++){
for(int j = i+1; j<N; j++){
if(visit[i] != visit[j]) continue;
if (visit[i])
start += player[i][j] + player[j][i];
else
link += player[i][j] + player[j][i];
}
}
// 두 팀의 능력치 차이
int diff = Math.abs(start - link);
if(diff < result) result = diff;
return;
}
visit[cnt] = true;
solve(cnt+1);
visit[cnt] = false;
solve(cnt+1);
}
}
728x90
'Algorithm > Baekjoon' 카테고리의 다른 글
[백준] 2170번 선 긋기 (JAVA) (0) | 2023.02.09 |
---|---|
[백준] 15486번 퇴사 2 (JAVA) (0) | 2023.02.09 |
[백준] 11866번 요세푸스 문제 0 (JAVA) (0) | 2023.02.03 |
[백준] 14225번 부분수열의 합 (JAVA) (0) | 2023.01.18 |
[백준] 18429번 근손실 (JAVA) (0) | 2023.01.15 |
댓글