코딩테스트 연습

[BOJ] 3980. 선발 명단 (backtracking, bruteforcing)

hio9_9 2023. 1. 9. 00:22

Gold V

https://www.acmicpc.net/problem/3980

 

3980번: 선발 명단

각각의 테스트 케이스에 대해서, 모든 포지션의 선수를 채웠을 때, 능력치의 합의 최댓값을 한 줄에 하나씩 출력한다. 항상 하나 이상의 올바른 라인업을 만들 수 있다.

www.acmicpc.net

챔피언스 리그 결승전을 앞두고 있는 맨체스터 유나이티드의 명장 퍼거슨 감독은 이번 경기에 4-4-2 다이아몬드 전술을 사용하려고 한다.

오늘 결승전에 뛸 선발 선수 11명은 미리 골라두었지만, 어떤 선수를 어느 포지션에 배치해야 할지 아직 결정하지 못했다.

수석코치 마이크 펠란은 11명의 선수가 각각의 포지션에서의 능력을 0부터 100까지의 정수로 수치화 했다. 0은 그 선수가 그 포지션에 적합하지 않다는 뜻이다.

이때, 모든 선수의 포지션을 정하는 프로그램을 작성하시오. 모든 포지션에 선수를 배치해야 하고, 각 선수는 능력치가 0인 포지션에 배치될 수 없다.

 

input:

  • 입력은 여러 개의 테스트 케이스로 이루어져 있다. 첫째 줄에는 테스트 케이스의 개수 C가 주어진다.
  • 각각의 케이스는 11줄로 이루어져 있고, i번 줄은 0과 100사이의 11개의 정수 sij를 포함하고 있다. sij는 i번선수가 j번 포지션에서 뛸 때의 능력이다. 모든 선수에게 적합한 포지션의 수는 최대 5개이다. (능력치가 0보다 크다)

output:

  • 각각의 테스트 케이스에 대해서, 모든 포지션의 선수를 채웠을 때, 능력치의 합의 최댓값을 한 줄에 하나씩 출력한다. 항상 하나 이상의 올바른 라인업을 만들 수 있다.

 


Idea :

  • 팀의 능력치가 최대가 되는 배치 조합을 찾아야 함
  • 각각의 위치에 어떤 선수를 배치하느냐에 따라 팀의 능력치가 달라짐
  • 순열 문제 → DFS

Code :   

#include <iostream>

using namespace std;

int stat[11][11] = {};  // input으로 주어지는 포지션의 따른 각 선수의 능력치
int perm[11] = {};      // 선수 배치 조합
int max_stat = 0;       // 팀 능력치 최댓값

/* solve: 선수 배치 조합을 구하고, 팀 능력치의 최댓값을 구하는 함수 
 *
 * parameters - player: 0-10 번 중 포지션을 배치할 선수 번호
 *            - visited: 이미 선수를 배치한 포지션 정보
 *            - team_stat: player-1까지 배치했을 때의 팀 능력치 
 * no return
 */
void solve(int player, int visited, int team_stat) {
	if (player == 11) {	// 모든 선수를 배치했을 때
		if (team_stat > max_stat) max_stat = team_stat;
		return;
	}

	for (int pos=0; pos<11; pos++) {
		if ((visited & (1 << pos)) != 0) continue;  // 이미 선수를 배치한 포지션일 경우
		if (stat[player][pos] == 0) continue;       // 해당 포지션에서의 선수의 능력치가 0인 경우
		solve(player+1, visited | (1 << pos), team_stat + stat[player][pos]);
	}
}

int main() {
	ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	// freopen("input.txt", "rt", stdin);

	int TC;
	
	cin >> TC;
	while (TC--) {
		/* init & input */
		for (int i=0; i<11; i++) {
			for (int j=0; j<11; j++)
				cin >> stat[i][j];
		}
		max_stat = 0;

		/* solve */
		solve(0, 0, 0);
		cout << max_stat << "\n";
	}

}

 


Result : 

메모리: 2020 KB,  시간: 4 ms

 

Review :