알고리즘 풀이/백준

[백준 14889] 스타트와 링크 cpp

mhko411 2021. 3. 10. 22:59
728x90

문제
스타트링크에 다니는 사람들이 모여서 축구를 한다. 모인 사람은 항상 짝수인 N명이 모였으며 스타트팀과 링크팀으로 나누려고 한다.
이때 i와 j가 팀이 되었을 때 능력치가 있는데 N명이 두 팀으로 나눴을 때 각각 팀의 능력치를 구하여 두 팀의 능력치 차이가 최소가 되도록 구하라.

입력
첫째 줄에 N이 주어진다.
둘째 줄부터 N개의 줄에 N개의 능력치가 주어진다.
i번째 줄의 j번째 수는 i와 j가 팀이 되었을 때 능력치이다.

출력
스타트팀과 링크 팀의 능력치의 차이가 최소가 되는 값을 출력한다.


접근

먼저 두 개의 팀으로 나눴다. 스타트팀은 1, 링크팀은 0으로 표시를 한다.

이후 능력치를 조사하는데 2차원 배열을 탐색할 때 행과 열의 인덱스가 모두 1일 때는 스타트 능력치에 더하고 모두 0일 때는 링크 능력치에 더하여 차이의 최솟값을 찾는다.

 

구현

solve()에서 먼저 두 개의 팀으로 나누도록 한다. team배열이 0이라면 1로 표시를 하고 picked를 증가시켜 재귀호출을 한다.

이후 picked가 N의 반이라면 각 팀의 능력치를 구하고 두 팀의 능력치 차이를 구하여 최종해를 위한 비교를 한다.

#include <iostream>
#include<algorithm>
#include <vector>
#include<queue>
#include<cmath>
using namespace std;

int N;
int answer = 1001;
int team[20];
int stats[20][20];

void solve(int next, int picked) {
	if (picked == (N / 2)) {
		int start_stat = 0;
		int link_stat = 0;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (team[i] == 1 && team[j] == 1) {
					start_stat += stats[i][j];
				}
				else if (team[i] == 0 && team[j] == 0) {
					link_stat += stats[i][j];
				}
			}
		}
		answer = min(answer, abs(start_stat - link_stat));
		
	}
	for (int i = next; i < N; i++) {
		if (!team[i]) {
			team[i] = 1;
			solve(i + 1, picked + 1);
			team[i] = 0;
		}
	}
}
int main()
{
	cin >> N;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cin >> stats[i][j];
		}
	}

	solve(0, 0);
	cout << answer << endl;
	
}

'알고리즘 풀이 > 백준' 카테고리의 다른 글

[백준 17142] 연구소 3  (0) 2021.03.15
[백준 2206] 벽 부수고 이동하기  (0) 2021.03.15
[백준 14888] 연산자 끼워넣기  (0) 2021.03.10
[백준 14501] 퇴사  (0) 2021.03.09
[백준 15657] N과 M (8)  (0) 2021.03.09