티스토리 뷰

문제

- 축구를 하기 위해 모인 사람은 총 N명

- 스타트 팀과 링크 팀으로 사람들을 나눠야 함

- 두 팀의 인원수는 같지 않아도 되지만, 한 명 이상이어야 함

- 각 사람에게 번호를 1 ~ N까지 배정하고 능력치를 조사함

- S[ij]는 i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치

- 팀의 능력치는 팀에 속한 모든 쌍의 능력치의 합

- 스타트 팀의 능력치와 링크 팀의 능력치의 차이를 최소로 하려 함

 

해결방법

부분집합으로 팀을 구성할 수 있는 인원들을 뽑은 뒤, 각 팀별로 능력치를 합산하고 차이를 비교해 정답을 구할 수 있도록 구성하였다.

부분집합을 구하는 코드는 아래 포스팅을 참고하면 좋을 것 같다.

 

[알고리즘] 부분집합(Subset)

부분집합(Subset) 개념 - 집합에 포함된 원소들을 선택하는 것 - 아무 것도 안 뽑는 것부터 전체 다 뽑는 것까지 조합의 경우를 다 더한 것과 같음 - 부분집합을 이용하여 조합으로 사용하고 싶으면

sa11k.tistory.com

 

코드

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);
    }
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday