📖 문제
15661번: 링크와 스타트
첫째 줄에 N(4 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에 S가 주어진다. 각 줄은 N개의 수로 이루어져 있고, i번 줄의 j번째 수는 Sij 이다. Sii는 항상 0이고, 나머지 Sij는 1보다 크거나 같고, 100
www.acmicpc.net
💡 풀이 방식
• 백트래킹
부분집합 (재귀) 을 활용해 팀을 나누고, 각 팀별로 능력치를 합하고 그 차이를 최솟값과 비교해 정답으로 출력한다.
💥 유의사항
두 팀의 인원수는 같지 않아도 되지만, 한 명 이상이어야 한다. → 부분집합
🔺 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import java.util.*;
import java.io.*;
public class Main {
static int N;
static int[][] S;
static boolean[] chk; // 🔔 해당 사람 뽑았는지 확인용 배열
static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
S = new int[N][N];
chk = new boolean[N];
for(int i = 0 ; i < N ; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 0 ; j < N ; j++) {
S[i][j] = Integer.parseInt(st.nextToken());
}
}
dfs(0);
System.out.println(min);
}
private static void dfs(int cnt) { // 🔔 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(chk[i] != chk[j]) continue;
if(chk[i]) start += S[i][j] + S[j][i];
else link += S[i][j] + S[j][i];
}
}
min = Math.min(min, Math.abs(start - link));
return;
}
// 해당 cnt번 사람 선택해 스타트 팀에 넣음
chk[cnt] = true;
dfs(cnt + 1);
// 해당 cnt번 사람 비선택해 링크 팀에 넣음
chk[cnt] = false;
dfs(cnt + 1);
}
}
|
cs |
➕ 다른 풀이 방식
(조합 ver.) 팀의 인원 수를 (1, N-1) (2, N-2), .. (M, N-M) 이렇게 모든 경우에 대해 탐색하며 진행하셨다.
그리고 dfs 방식할 때 재귀함수에서 (인자, 뽑은 갯수) 인자로 들고 다니면서 내가 작성하던 방식과 같게 하심
[백준] 15661 링크와 스타트 - 완전탐색 (DFS) JAVA
https://www.acmicpc.net/problem/15661 15661번: 링크와 스타트 첫째 줄에 N(4 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에 S가 주어진다. 각 줄은 N개의 수로 이루어져 있고, i번 줄의 j번째 수는 Sij 이다. Si
passionfruit200.tistory.com
[ BOJ ][JAVA][15661] 링크와 스타트
www.acmicpc.net/problem/15661 15661번: 링크와 스타트 첫째 줄에 N(4 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에 S가 주어진다. 각 줄은 N개의 수로 이루어져 있고, i번 줄의 j번째 수는 Sij 이다. Sii는 항
coder-in-war.tistory.com
💦 어려웠던 점
- 부분집합을 써야겠단 생각까지는 들었는데 백트래킹 함수를 제대로 작성했는지에 확신이 없었다. (그리고 실제로 틀리게 작성했었다) 다시 복습을 해야겠따..
- 백트래킹 깊이를 어떻게 바꾸지?에 대한 부분이 어려웠다.
- 스타트와 링크 문제와 비슷하다 하여 이 문제와 다른 부분집합 문제들을 풀어보도록 하겠다.
🧐 새로 알게 된 내용
부분집합 개념!!!
[Java]부분 집합(Subset)과 멱집합(Power Set)
*부분 집합(Subset) -> 부분 집합이란 쉽게 말해서 어떤 집합에 포함되는 집합을 말한다. 말 그대로 어떤 집합의 '부분'이 되는 집합이라고 생각하면 된다. Ex) {1, 2, 3}의 부분 집합은 공집합, {1}, {2},
sskl660.tistory.com
부분집합 PowerSet (Java)
부분집합연습 문제 배열의 모든 부분집합을 구합니다. 배열 [1, 2, 3] 이 있다면 부분집합은 [1] [2] [3] [1, 2] [1, 3] [2, 3] [1, 2, 3]입니다. 뭔가 떠오르지 않나요? 바로 조합이 떠오릅니다. 저번에 포스
bcp0109.tistory.com
[Java] 부분집합(Subset)
부분집합(Subset) 부분집합 : 한 집합에 포함될 수 있는 모든 집합들, 부분집합의 수는 2의n승이다. [입력] 3 1 2 3 [출력] 1 2 3 1 2 X 1 X 3 1 X X X 2 3 X 2 X X X 3 X X X [변수] - N : 존재하는 원소의 수 - input :
java-is-happy-things.tistory.com
[알고리즘] 부분집합(Subset)
부분집합(Subset) 개념 - 집합에 포함된 원소들을 선택하는 것 - 아무 것도 안 뽑는 것부터 전체 다 뽑는 것까지 조합의 경우를 다 더한 것과 같음 - 부분집합을 이용하여 조합으로 사용하고 싶으면
sa11k.tistory.com
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V |
(참고)
✔ 풀이 참고 : https://sa11k.tistory.com/56 , https://bbangson.tistory.com/50
✔ 내가 진행하려고 했던 방향과 같으심
[백준] 15661번 링크와 스타트 풀어보기 [Java]
이 문제가 틀려있길래 풀었는데, 왜 틀렸었지라는 의문이 들었다.... 사람들을 두 팀으로 나눠서 능력치를 비교하여서, 최솟값을 찾는 문제이다. 각 사람들은 자기와 같은 팀을 이룬 사람과 함께
peace-log.tistory.com
이거 완전 재귀의 총집합!!!
[Java] 순열 / 조합 / 부분 집합 정리 (수도 코드 - 재귀편)
순열 서로 다른 n개의 원소 중 r개를 순서 있게 골라낸 것을 순열(Permutation)이라고 한다. 아래 코드는 주사위를 3번 던졌을 때 나올 수 있는 경우의 수이다. (중복 X, 순서 O) // 순열 : nPr ==> n! private
sohee-dev.tistory.com
'코테 > 백준' 카테고리의 다른 글
[백준/JAVA] 10164번: 격자상의 경로 (0) | 2024.02.15 |
---|---|
[백준/JAVA] 15489번: 파스칼 삼각형 (0) | 2024.02.12 |
[백준/JAVA] 16946번: 벽 부수고 이동하기 4 (0) | 2024.02.08 |
[백준/JAVA] 2961번: 도영이가 만든 맛있는 음식 (1) | 2024.02.07 |
[백준/JAVA] 16973번: 직사각형 탈출 (0) | 2024.02.07 |