https://www.acmicpc.net/problem/1182
부분수열의 합
1) 문제
N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.
입력: 첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.
출력: 첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.
출력: 첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.
2) 예시
예제입력 1:
5 0
-7 -3 -2 5 8
예제출력 1:
1
3) 풀이
* 아이디어
1. 모든 부분수열을 탐색해야 하므로 → 부분집합 문제
→ 각 원소를 “고를지 / 안 고를지”의 두 가지 선택으로 분기
2. DFS 재귀를 이용해 모든 조합을 탐색
→ dfs(index + 1, sum + arr[index]) (현재 원소 선택)
→ dfs(index + 1, sum) (현재 원소 미선택)
3. 합이 목표값 S와 일치하는 경우만 count 증가
공집합은 제외해야 하므로 S == 0일 경우 count-- 처리 필요 (선택을 아무것도 안 한 경우)
4) 코드
import java.util.Scanner;
// Scanner 클래스를 불러옴
public class Main {
// 자바 시작점인 클래스_ 백준에서는 Main으로 정의해야함
static int N, S, count;
// 수열의길이N, 목표로하는 부분수열합 S, 조건에맞는경우의수count 변수
static int[] arr;
// 입력받은 수열을 저장한 정수배경
public static void dfs(int index, int sum) {
// dfs 메소드 정의, index는 현재 탐색중인 배열위치, sum은 지금까지 선택한 숫자의합
if (index == N) {
// 모든 원소를 탐색했을 때(배열 끝에 도달했을때)
if (sum == S) {
count++;
}
// 현재까지 구한 수열의합이 목표값인 S와 같을 경우 count 1증가 (정답을 세는 조건)
return;
}
// 현재 숫자를 포함하는 경우
dfs(index + 1, sum + arr[index]);
// 인덱스를 1 증가시키고, 해당 값을 sum에 더해서 다음 DFS로 진행
// 현재 숫자를 포함하지 않는 경우
dfs(index + 1, sum);
// sum은 그대로 유지한 채 다음 인덱스로 진행
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt(); // 수열 길이
S = sc.nextInt(); // 목표 합
arr = new int[N];
// 수열을 저장할 배열 선언
for (int i = 0; i < N; i++) {
arr[i] = sc.nextInt();
}
// 배열의 각 요소를 사용자로부터 입력받아 저장
dfs(0, 0);
// index = 0부터 시작, 현재 합은 0
// 공집합 제외
if (S == 0) count--;
// 아무것도 선택하지 않은 경우에도 sum == 0일 수 있음
// 하지만 문제는 “공집합은 제외”라고 명시했기 때문에
// S == 0일 때 count에서 1을 빼줌
System.out.println(count);
}
}

5) 리뷰
공집합의 경우 합이 0이 될 수 있어서 예외 처리를 해줘야 한다는 조건이 기억에 남는다.
재귀 흐름이 익숙하지 않은 상태였지만, 호출 순서를 하나씩 따라가다 보니
부분집합을 탐색하는 기본 패턴을 체득할 수 있는 좋은 연습 문제였다.
'Baekjoon Coding Test > Java' 카테고리의 다른 글
[백준 14503] Java - 로봇 청소기 (0) | 2025.05.22 |
---|---|
[백준 9663] Java - N-Queen (0) | 2025.05.22 |
[백준 15649] Java - N과 M (1) (0) | 2025.05.03 |
[백준 10870] Java - 피보나치 수 5 (0) | 2025.05.02 |
[백준 1926] Java - 그림 (0) | 2025.04.03 |