πŸ“– [λ°±μ€€μ•Œκ³ λ¦¬μ¦˜ 풀이] Q.1182 λΆ€λΆ„μˆ˜μ—΄μ˜ ν•© 문제 풀이

πŸ“– 문제

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

N개의 μ •μˆ˜λ‘œ 이루어진 μˆ˜μ—΄μ΄ μžˆμ„ λ•Œ, 크기가 μ–‘μˆ˜μΈ λΆ€λΆ„μˆ˜μ—΄ μ€‘μ—μ„œ

κ·Έ μˆ˜μ—΄μ˜ μ›μ†Œλ₯Ό λ‹€ λ”ν•œ 값이 Sκ°€ λ˜λŠ” 경우의 수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 μ •μˆ˜μ˜ 개수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Nκ³Ό μ •μˆ˜ Sκ°€ 주어진닀. (1 ≀ N ≀ 20, |S| ≀ 1,000,000)

λ‘˜μ§Έ 쀄에 N개의 μ •μˆ˜κ°€ 빈 칸을 사이에 두고 주어진닀. μ£Όμ–΄μ§€λŠ” μ •μˆ˜μ˜ μ ˆλŒ“κ°’μ€ 100,000을 λ„˜μ§€ μ•ŠλŠ”λ‹€.

좜λ ₯

첫째 쀄에 합이 Sκ°€ λ˜λŠ” λΆ€λΆ„μˆ˜μ—΄μ˜ 개수λ₯Ό 좜λ ₯ν•œλ‹€.

πŸ” 접근법

Q.1182 λΆ€λΆ„μˆ˜μ—΄μ˜ ν•© 문제 ν’€μ΄μž…λ‹ˆλ‹€.

λΆ€λΆ„μˆ˜μ—΄μ€ μ—°μ†λ˜μ§€ μ•Šμ•„λ„ 되기 λ•Œλ¬Έμ— λͺ¨λ“  경우λ₯Ό μ‚΄νŽ΄λ³΄μ•„μ•Ό ν•©λ‹ˆλ‹€.

완전탐색을 톡해 ν’€μ–΄μ•Ό ν•˜λŠ”λ°

κ·Έμ€‘μ—μ„œλ„ κ³±μ…ˆμ΄λ‚˜ λ‚˜λˆ—μ…ˆ 같은 것이 μ—†κ³  μ˜€λ‘œμ§€ ν•©μ΄λ―€λ‘œ

λΆ€λΆ„μˆ˜μ—΄μ„ μ„ νƒν•˜λŠ” μˆœμ„œκ°€ 상관이 μ—†μŠ΅λ‹ˆλ‹€.

즉, μˆœμ„œμ— μƒκ΄€μ—†λŠ” 선택 문제둜

μ‘°ν•©μœΌλ‘œ N개 쀑 1κ°œλΆ€ν„°~Nκ°œκΉŒμ§€ λ½‘λŠ” λͺ¨λ“  경우의 수λ₯Ό 뽑고 (nC1 . . . nC2 . . . nCn)

κ·Έ 쀑 μ„ νƒν•œ λΆ€λΆ„μˆ˜μ—΄μ˜ 합이 주어진 S와 같을 λ•Œ

countλ₯Ό 늘렀주면 닡을 λ„μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ’» μ½”λ“œ

package problem.brute;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main_1182 {
    static int n, s;
    static int[] nums;
    static int count = 0;
    public static void main(String[] args) throws IOException {
        input();
        solve();
        System.out.println(count);
    }



    public static void input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String [] input = br.readLine().split(" ");
        n = Integer.parseInt(input[0]);
        s = Integer.parseInt(input[1]);
        nums = new int[n];

        String[] temp = br.readLine().split(" ");
        for(int i=0; i<n; i++){
            nums[i] = Integer.parseInt(temp[i]);
        }
    }

    public static void solve() {
        boolean[] visited = new boolean[n];
        for(int i=1; i<=n ; i++){
            combination(nums, visited, 0, n,i);
        }
    }

    static void combination(int[] arr, boolean[] visited, int depth, int n, int r) {
        if (r == 0) {
            //λ‹€ 뽑은 λΆ€λΆ„μˆ˜μ—΄μ— λŒ€ν•΄ 합을 계산
            caculate(arr, visited, n);
            return;
        }

        if (depth == n) {
            return;
        }

        visited[depth] = true;
        combination(arr, visited, depth + 1, n, r - 1);

        visited[depth] = false;
        combination(arr, visited, depth + 1, n, r);
    }

    static void caculate(int[] arr, boolean[] visited, int n) {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            if (visited[i]) {
                sum+=arr[i];
            }
        }
        if(sum==s){
            count++;
        }
    }
}

Written on February 11, 2021