새소식

💻 Programming (프로그래밍)/C++ | 백준

[C++][백준] - 링크와 스타트 (15661번)

  • -
https://www.acmicpc.net/problem/15661
 

15661번: 링크와 스타트

첫째 줄에 N(4 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에 S가 주어진다. 각 줄은 N개의 수로 이루어져 있고, i번 줄의 j번째 수는 Sij 이다. Sii는 항상 0이고, 나머지 Sij는 1보다 크거나 같고, 100

www.acmicpc.net

🔔 문제 : 

축구게임을 하기 위한 사람 N명이 주어집니다. ( 4<= N <= 20)

 

그리고 각 사람마다 시너지를 점수화한 점수판이 주어집니다.

 

예를들면 이런식으로 주어집니다.

i/j 1 2 3 4
1 0 1 2 3
2 4 0 5 6
3 7 1 0 2
4 3 4 5 0

 

i, j 는 사람의 번호를 의미하고 그에 맞는 수들은 시너지를 의미합니다.

 

이 시너지가 최솟값이 되는 팀을 짜서 최솟값을 구하는 문제입니다.

 

시너지는 1 <= x <= 100인 정수이고, 두 팀은 인원수는 같지 않아도 되지만 한 명 이상이여야 합니다.


🔔 Kick Point :

사람을 뽑는 것이기 때문에 사람을

DFS를 이용하여 뽑으면서 조건에 맞게 추리면 됩니다.

 

DFS가 이뤄지는 순서는 

G_visited 배열이 A팀의 사람이라 생각하고

 

1명부터 N/2명까지 각 팀에 해당하는 숫자에 맞게 구해주면 됩니다.

 

조합에 대해 자세한 알고리즘을 알고싶으면 이 포스팅을 참고해주세요

2022.03.03 - [백준] - [C++][백준] - N과 M (2) (15650번)

 

[C++][백준] - N과 M (2) (15650번)

https://www.acmicpc.net/problem/15650 15650번: N과 M (2) 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.

meta-jun.tistory.com


변수

G_power[MAX][MAX] : 사람간의 시너지 점수

G_visited[MAX] : A팀의 선택된 사람 (한 팀을 알면 자연스럽게 B팀을 알수있다)

G_n : 사람 숫자 N명

G_Result : 시너지 최솟값 (초기값 10000000 은 최댓값 20*20*100 보다 크기 위해 만듬)

 

함수

Input : G_power인 시너지 점수를 입력

Cal : a팀과 b팀의 시너지 점수를 계산하여 빼줘서 최솟값을 구함

DFS : 재귀적 방법의 백트래킹을 사용하여 팀의 경우의 수를 구함

Sol : 1명부터 N/2명까지 팀을 선별하며 문제를 진행해가는 함수이며 G_Result를 출력함

🔔 Code :

#include <iostream>
#include <cmath>
#define endl '\n'
#define MAX 20

using namespace std;

int G_power[MAX][MAX];
bool G_visited[MAX] = { false, };
int G_n;
int G_Result = 100000000;


void Input(int n = 0) {
	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {

			cin >> G_power[i][j];

		}
	}
}

int Cal() {
	int aTeam = 0;
	int bTeam = 0;

	// aTeam;
	for (int i = 0; i < G_n; i++) {
		for (int j = 0; j < G_n; j++) {
			if (G_visited[i] && G_visited[j]) {
				aTeam += G_power[i][j];
			}
		}
	}	
	// bTeam;
	for (int i = 0; i < G_n; i++) {
		for (int j = 0; j < G_n; j++) {
			if (!G_visited[i] && !G_visited[j]) {
				bTeam += G_power[i][j];
			}
		}
	}


	return (abs(aTeam - bTeam));
}

void DFS(int cnt = 0, int num = 0, int n =0) {
	
	if (cnt == num) {
		int tmp = Cal();
		if (tmp < G_Result) G_Result = tmp;
		return;
	}

	for (int i = n; i < G_n; i++) {

		if (!G_visited[i]) {
			G_visited[i] = true;
			DFS(cnt + 1, num, i+1);
			G_visited[i] = false;
		}
	}
}

void Sol() {

	for (int i = 1; i <= G_n / 2; i++) {
		DFS(0, i, 0);
		for (int i = 0; i < G_n; i++) { G_visited[i] = false; }

	}

	cout << G_Result;
}


int main() {

	cin >> G_n;
	Input(G_n);
	Sol();

}

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.