점점 강해지고 있습니다.
[Java] 백준 1182번: 부분수열의 합
문제
N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, | S | ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다. |
출력
첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.
예제 입력 1
5 0
-7 -3 -2 5 8
예제 출력 1
1
풀이 방법
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
public class BOJ_1182_부분수열의합 {
static int N, S, res;
static int[] arr;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
S = Integer.parseInt(st.nextToken());
arr = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
subset(0, new boolean[N]);
System.out.println(res);
}
private static void subset(int idx, boolean[] sel) {
if(idx == N) {
int sum = 0;
boolean isNull = true;
for (int i = 0; i < sel.length; i++) {
if(sel[i]) {
sum += arr[i];
isNull = false;
}
}
if(sum == S && !isNull) {
res++;
}
return;
}
sel[idx] = true;
subset(idx+1, sel);
sel[idx] = false;
subset(idx+1, sel);
}
}
수열의 합을 계산하기 위해 부분집합을 사용해서 모든 경우의 수를 구했다.
예제에서 숫자 1이 결과로 나와야 하는데 2가 나와서 생각해보니 공집합도 함께 계산되어서 결과가 달라지는 것이었다.
공집합을 제외하기 위해 -1를 결과에 더해주고 제출하였는데 틀렸습니다.
가 떠서 생각해보니 결과가 0일 때 -1이 출력되는 것이라는 걸 깨닫고 수정 제출했더니 통과!
Thank You For Reading