본문 바로가기

코딩테스트

백준 14225번: 부분수열의 합[JAVA]

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

 

14225번: 부분수열의 합

수열 S가 주어졌을 때, 수열 S의 부분 수열의 합으로 나올 수 없는 가장 작은 자연수를 구하는 프로그램을 작성하시오. 예를 들어, S = [5, 1, 2]인 경우에 1, 2, 3(=1+2), 5, 6(=1+5), 7(=2+5), 8(=1+2+5)을 만들

www.acmicpc.net

 

 

[정답 코드]

import java.io.*;
import java.util.*;

public class Main {
    static int[] arr, answer;
    static int N, max = 0;
    static boolean[] visited;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        N = Integer.parseInt(st.nextToken());

        arr = new int[N];
        visited = new boolean[N];

        st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
            max += arr[i];
        }
        answer = new int[max + 2]; // 최대 가능한 합 + 2 로 설정해야 메모리 낭비를 막을 수 있다

        dfs(0, 0);

        for (int i = 1; i < answer.length; i++) {
            if (answer[i] == 0) { // 0일 경우 해당 인덱스는 나온적 없는 숫자이므로 출력
                System.out.println(i);
                break;
            }
        }

    }

    static void dfs(int depth, int sum) {
        if (depth == N) { // depth 가 N일 경우 종료
            answer[sum] = 1; // 현재까지 저장된 sum 값은 이미 나온 숫자이므로 1로 변경
            return;
        }
        dfs(depth + 1, sum + arr[depth]); // 현재까지 저장된 sum + 현재 인덱스의 arr 값
        dfs(depth + 1, sum); // 현재 인덱스의 arr 값을 추가하지않고 다음 인덱스 탐색
    }
}

 

[설명]

배열의 원소를 입력받을 때마다 값을 max에 추가해 나올 수 있는 가장 큰 자연수를 계산한다. 나올 수 있는 자연수들이 담긴 배열 answer = new int[max+ 2] 해준다. 다른 코드에서는 문제에서 주어진 나올 수 있는 가장 큰 값으로 초기화 해주었지만 max가 적을수록 메모리낭비가 생기기 때문에 이처럼 해준다.

 

dfs로직 : 매개변수로 depth, sum을 받는다. depth는 현재의 인덱스 위치, sum은 현재까지 저장된 값이다. depth 가 N이 될 경우 초기에는 answer배열의 모든값이 0이기 때문에 answer[sum]을 임의의 값 1로 변경해준후 return 한다.

        dfs(depth + 1, sum + arr[depth]); // 현재까지 저장된 sum + 현재 인덱스의 arr 값
        dfs(depth + 1, sum); // 현재 인덱스의 arr 값을 추가하지않고 다음 인덱스 탐색

이 부분은 배열의 완전탐색을 하기위한 알고리즘이다. 인덱스를 증가시키면 배열을 탐색하다 현재 인덱스의 arr[depth] 더하고 다음 인덱스를 탐색할 경우에는 첫 번째를, 아니라면 두 번째를 실행해야한다. 모든 배열을 탐색해야하기 때문에 두 가지 모두 수행한다.

'코딩테스트' 카테고리의 다른 글

백준 1189번: 컴백홈[JAVA]  (0) 2024.03.28
백준 15686번: 치킨 배달[JAVA]  (0) 2024.03.28
백준 10819번: 차이를 최대로[JAVA]  (0) 2024.03.21
백준 1260번: DFS와 BFS[JAVA]  (0) 2024.03.20
백준 1068번: 트리[JAVA]  (1) 2024.03.15