본문 바로가기
  • 개발 삽질 블로그
프로그래밍/백준 문제풀이

백준 1182: 부분수열의 합

by 갹둥 2022. 11. 17.

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

 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net

이 문제는 멱집합을 구하는 알고리즘을 조금 변형하면 풀 수 있다. k번 째 원소를 뽑거나 안 뽑거나에 따라 합이 달라진다. 

k번째 원소를 합한 값, 합하지 않은 값을 넘겨 재귀호출한다.

 

import java.util.*;
public class Main {
	static int powerSet(int[] arr, int s, int target, int k) {
		int cnt=0;
		
		if(k==arr.length) {
			if(s==target)
				return 1;
			else
				return 0;
		}

		cnt+=powerSet(arr, s, target, k+1);
		cnt+=powerSet(arr, s+arr[k], target, k+1);
		
		return cnt;
	}


	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int s = sc.nextInt();
		int[] arr = new int[n];

		for(int i=0; i<n; i++)
			arr[i] = sc.nextInt();
		
		int count = powerSet(arr, 0, s, 0);
		
		if(s!=0)
			System.out.println(count);
		else
			System.out.println(count-1); //공집합까지 카운트하는 경우
	}
}

s가 0인 경우에는 공집합인 경우에도 카운트하므로 1을 빼줘야 한다. 처음에는 이 부분을 생각하지 못해 틀렸다.

'프로그래밍 > 백준 문제풀이' 카테고리의 다른 글

백준 1463: 1로 만들기  (1) 2022.11.30
백준 6603: 로또(JAVA)  (0) 2022.11.30
백준 10974: 모든 순열  (0) 2022.10.13
백준 10973: 이전 순열(JAVA)  (0) 2022.10.12
백준 10972: 다음 순열(JAVA)  (0) 2022.10.12