https://www.acmicpc.net/problem/14889
14889번: 스타트와 링크
예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.
www.acmicpc.net
풀이
이 문제를 처음 보았을때는 개인적으로는 실버3 같이 느껴지지 않았다. 나는 처음에 사람들의 집중하기보다는 점수들의 조합에 집중해서 어려웠던것 같다.
알고리즘의 개요는 다음과 같다. 모든 사람들의 조합을 구하고 각 조합당 낼수있는 시너지들의 총합을 구하고 이를 스타트와 링크로 나누너 계산해 가장 작은값을 출력하면 된다. 자세한것은 코드를 보면서 이해가 될것이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Main{
public static int N; //입력값 저장
public static int [][]map; //낼수있는 시너지들을 저장하는 공간
public static boolean [] visit; //사람들
public static int Min = Integer.MAX_VALUE; //최소값
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new int[N][N];
visit = new boolean[N];
StringTokenizer st;
for(int i=0; i<N; i++){
st = new StringTokenizer(br.readLine(), " ");
for(int j=0 ; j<N; j++){
map[i][j] = Integer.parseInt(st.nextToken());
}
}
combi(0,0);
System.out.println(Min);
}
public static void combi(int depth, int idx){ //탐을 만들어주는 함수
if(depth == N/2){
diff(); // 각 팀원들의 최소값 계산
return;
}
for(int i = idx; i<N; i++){
if(!visit[i]){
visit[i] = true;
combi(depth+ 1 , i + 1); // 팀원이 만들어지지 않았다면 재귀호출로 다시 들어감
visit[i] = false; // 방문후 미방문으로 처리
}
}
}
public static void diff(){ // 시너지 차이 계산해주는 함수
int team_start = 0;
int team_link = 0;
for(int i=0; i<N-1; i++){ //i가 N-1일 경우 j는 N가 된다. 이는 아래의 반복문을 들어가도 바로 빠지기 때문에 N-1로 범위 설정
for(int j=i+1; j<N; j++){
if(visit[i]==true && visit[j]==true){ // 둘다 방문하였을경우 true로 처리
team_link += map[i][j];
team_link += map[j][i];
}
else if(visit[i] == false && visit[j] == false){ // 둘다 미방문시 false로 처리
team_start += map[i][j];
team_start += map[j][i];
}
}
}
int val = Math.abs(team_link- team_start); // 시너지 점수의 차이의 절댓값
if(val == 0){ // 만약 0인 경우 이 이상 시너지 차이가 작아질수없으르모 출력하고 프로그램 종료
System.out.println(val);
System.exit(0);
}
Min = Math.min(val, Min); // 기존의 최소값과 비교
}
}
'백준' 카테고리의 다른 글
[백준] 1759 암호 만들기 (JAVA) (0) | 2021.10.06 |
---|---|
[백준] 5639 이진 검색 트리 (JAVA) (0) | 2021.10.05 |
[백준] 15650 N과 M (2) (JAVA) (0) | 2021.10.02 |
[백준] 14888 연산자 끼워넣기 (JAVA) (0) | 2021.09.30 |
[백준] 15649 N과M(1) (JAVA) (0) | 2021.09.28 |