ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BOJ] 부분 수열의 합
    알고리즘 2023. 10. 5. 23:39

    문제

    N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.

    풀이

    우선 부분수열이란 걸 뭔지 정리하고 가자.
    수열을 집합으로 보자.
    이때의 부분집합을 부분수열이라고 한다.
    가령 {1,2,3,4} 수열이 있다면 {1}, {2}, {3}, {1,2}, {1, 3}... 이런 것들이
    모두 부분수열이라는 것이다.
    부분수열이라고 해서 연속될 필요는 없는 것이다.
    필자는 후자의 의미로 이해하여 다음과 같은 풀이를 했었다.

    static void track(int N, int S, int[] arr, int start, int sum) {
            if (sum == S) {
                answer++;
            }
    
            if (start + 1 == N) {
                return;
            }
    
            track(N, S, arr, start + 1, sum + arr[start + 1]);
        }

    연속된다고 가정 하였을때 그 합을 구하는 풀이다.
    그러나 이것은 우리가 원하는 부분 수열이 아니다.
    각설하고, 여기서 원하는 것은 즉 조합임을 알 수 있다.
    따라서 조합을 구할때와 비슷한 풀이를 응용해서 하였다.

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class Main{
        static int answer = 0;
        static int N;
        static int S;   
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] str = br.readLine().split(" ");
            N = Integer.parseInt(str[0]);
            S = Integer.parseInt(str[1]);
    
            int[] arr = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    
            for(int i = 0; i < N; i++) {
                boolean[] visited = new boolean[N];
                track(0, i + 1, arr, visited, 0, 0);
            }
    
            System.out.println(answer);
        }
        //    5 0
    //    -7 -3 -2 5 8
        static void track(int depth, int r, int[] arr, boolean[] visited, int start, int sum) {
            if (depth == r) {
                if (sum == S) {
                    answer++;
                }
                return;
            }
    
            for(int i = start; i < N; i++) {
                if (!visited[i]) {
                    visited[i] = true;
                    track(depth + 1, r, arr, visited, i, sum + arr[i]);
                    visited[i] = false;
                }
            }
        }
    }

    자소서를 거의 다 썼고, 이제 다시 하던것을 재개할 생각이다.
    다시 달려보자구~~!

    https://github.com/Win-9/Algorism/tree/main/BOJ/%EB%B6%80%EB%B6%84%EC%88%98%EC%97%B4%EC%9D%98%20%ED%95%A9

    728x90

    '알고리즘' 카테고리의 다른 글

    [BOJ] N과M(3)  (0) 2023.10.09
    [BOJ] N과 M(2)  (0) 2023.10.06
    [BOJ] N-Queen  (0) 2023.09.24
    [BOJ] N과M(1)  (0) 2023.09.24
    [프로그래머스] 행렬의 곱셈  (0) 2023.09.23

    댓글

Designed by Tistory.