[Boj_1450] ๋ƒ…์ƒ‰๋ฌธ์ œ

๐Ÿ“Ž ๋ฌธ์ œ ๋งํฌ

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

 

โ–ธ ๋ฌธ์ œ

์„ธ์ค€์ด๋Š” N๊ฐœ์˜ ๋ฌผ๊ฑด์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ตœ๋Œ€ C๋งŒํผ์˜ ๋ฌด๊ฒŒ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋ฐฉ์„ ํ•˜๋‚˜ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

N๊ฐœ์˜ ๋ฌผ๊ฑด์„ ๊ฐ€๋ฐฉ์— ๋„ฃ๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

 

โ–ธ ์ž…๋ ฅ

์ฒซ์งธ ์ค„์— N๊ณผ C๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. N์€ 30๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ž์—ฐ์ˆ˜, C๋Š” 10^9๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์Œ์ด ์•„๋‹Œ ์ •์ˆ˜์ด๋‹ค. ๋‘˜์งธ ์ค„์— ๋ฌผ๊ฑด์˜ ๋ฌด๊ฒŒ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๋ฌด๊ฒŒ๋„ 10^9๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ž์—ฐ์ˆ˜์ด๋‹ค.

 

โ–ธ ์ถœ๋ ฅ

์ฒซ์งธ ์ค„์— ๊ฐ€๋ฐฉ์— ๋„ฃ๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

 

๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด

  • ๐Ÿฅ‡  ๋ฌธ์ œ ๋ ˆ๋ฒจ : ๊ณจ๋“œ 1
  • ๐Ÿ””  ๋ฌธ์ œ ์œ ํ˜• : ์ด๋ถ„ ํƒ์ƒ‰, ์ค‘๊ฐ„์—์„œ ๋งŒ๋‚˜๊ธฐ
  • ๐Ÿ’ฌ  ํ’€์ด ์–ธ์–ด : JAVA

 

๐Ÿค” ๋ฌธ์ œ ํ’€์ด

์ด ๋ฌธ์ œ๋Š” ๋ฌผ๊ฑด์˜ ์ˆ˜๊ฐ€ ์ตœ๋Œ€ 30๊ฐœ์ด๊ณ , ๊ฐ ๋ฌผ๊ฑด์€ ๊ฐ€๋ฐฉ์— ๋„ฃ๊ฑฐ๋‚˜ ๋„ฃ์ง€ ์•Š๋Š” ๋‘ ๊ฐ€์ง€ ์„ ํƒ์ง€๊ฐ€ ์žˆ๋‹ค. 
๋”ฐ๋ผ์„œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์™„์ „ํƒ์ƒ‰์œผ๋กœ ๊ณ„์‚ฐํ•˜๋ฉด ์ตœ๋Œ€ 2^30 ≈ 10์–ต ๊ฐ€์ง€ ๊ฒฝ์šฐ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. 
์ด๋Š” 1์ดˆ์— 1์–ต ๋ฒˆ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•ด๋„ 10์ดˆ ์ด์ƒ ๊ฑธ๋ฆฌ๋ฏ€๋กœ, ๋” ํšจ์œจ์ ์ธ ์ ‘๊ทผ์ด ํ•„์š”ํ•˜๋‹ค.

 

์ด๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๊ฐ€ ์ค‘๊ฐ„์—์„œ ๋งŒ๋‚˜๊ธฐ(Meet in the Middle) ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

 

์ค‘๊ฐ„์—์„œ ๋งŒ๋‚˜๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€ ? ๐Ÿค”

ํ•˜๋‚˜์˜ ๊ทธ๋ฃน ์ „์ฒด๋ฅผ ์™„์ „ํƒ์ƒ‰ํ•˜๊ธฐ ์–ด๋ ค์šธ ๋•Œ, ๋‘ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ๊ฐ์˜ ๊ฒฝ์šฐ๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ๋‹ต์„ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
ํƒ์ƒ‰ ๋Œ€์ƒ์„ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„๋ฉด ์—ฐ์‚ฐ๋Ÿ‰์ด ํฌ๊ฒŒ ์ค„์–ด๋“ ๋‹ค.

 

๐ŸŽฏ ๊ทธ๋ ‡๋‹ค๋ฉด ๋ฌธ์ œ์— ์ค‘๊ฐ„์—์„œ ๋งŒ๋‚˜๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•ด๋ณด์ž.

๋จผ์ €, ์ฃผ์–ด์ง„ ๋ฌผ๊ฑด์„ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„์–ด

  • ๊ทธ๋ฃน A : 0 ~ N/2 - 1
  • ๊ทธ๋ฃน B : N/2 ~ N - 1

๊ฐ ๊ทธ๋ฃน์—์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•œ๋‹ค.
๊ทธ ํ›„, ๊ทธ๋ฃน A์˜ ๋ถ€๋ถ„ํ•ฉ ํ•˜๋‚˜๋ฅผ ๊ณ ์ •ํ•˜๊ณ , ๊ทธ๋ฃน B์—์„œ C - ๋ถ€๋ถ„ํ•ฉ(A) ์ดํ•˜๊ฐ€ ๋˜๋Š” ๊ฐ’์˜ ๊ฐœ์ˆ˜๋ฅผ ์ฐพ์•„ ๋”ํ•œ๋‹ค.

๐Ÿ’ก ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜ ๊ตฌํ•˜๊ธฐ

weight1๊ณผ weight2๊ฐ€ ๊ฐ๊ฐ์˜ ๊ทธ๋ฃน(๋ฐฐ๋‚ญ)์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๊ณ„์‚ฐ๋œ๋‹ค.

  • ๋‘ ๊ทธ๋ฃน์˜ ๋ฌผ๊ฑด์„ ๋ชจ๋‘ ๋‹ด๋Š” ๊ฒฝ์šฐ
  • ๊ทธ๋ฃน A์˜ ๋ฌผ๊ฑด๋งŒ ๋‹ด๋Š” ๊ฒฝ์šฐ
  • ๊ทธ๋ฃน B์˜ ๋ฌผ๊ฑด๋งŒ ๋‹ด๋Š” ๊ฒฝ์šฐ
  • ๋‘˜ ๋‹ค ๋‹ด์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

 

๐Ÿง  ์ •๋ ฌ๊ณผ ์ด๋ถ„ ํƒ์ƒ‰

๊ทธ๋ฃน B์˜ ๋ถ€๋ถ„ํ•ฉ ๋ฐฐ์—ด(sum2)์„ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค.
์ •๋ ฌ์„ ํ•˜๋ฉด ํŠน์ • ๊ฐ’ ์ดํ•˜์˜ ์›์†Œ ๊ฐœ์ˆ˜๋ฅผ ์ด๋ถ„ ํƒ์ƒ‰์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

  • sum1[i]๋ฅผ ๊ธฐ์ค€์œผ๋กœ target = C - sum1[i] ๊ณ„์‚ฐ
  • sum2์—์„œ target ์ดํ•˜์ธ ์›์†Œ ๊ฐœ์ˆ˜ = upperBound(sum2, target)

์ด ๊ณผ์ •์„ ๋ชจ๋“  sum1[i]์— ๋Œ€ํ•ด ๋ฐ˜๋ณตํ•˜๊ณ , ๊ทธ ๊ฐœ์ˆ˜๋ฅผ ๋ชจ๋‘ ํ•ฉ์‚ฐํ•˜๋ฉด ์ „์ฒด ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๋œ๋‹ค.

 

์œ„ ํ’€์ด์˜ ์ฝ”๋“œ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ „์ฒด์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

โœ” ์ฝ”๋“œ

๋ฉ”๋ชจ๋ฆฌ : 17288KB
์‹œ๊ฐ„ : 168ms
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class Main {
    static int n, c;
    static int[] arr;
    static ArrayList<Integer> left, right;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken()); // ๋ฌผ๊ฑด์˜ ๊ฐœ์ˆ˜
        c = 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());
        }

        left = new ArrayList<>();
        right = new ArrayList<>();
        comb(left, 0, n/2, 0);
        comb(right, n/2, n, 0);
        Collections.sort(right);

        int ans = 0;
        for (int i = 0; i < left.size(); i++) {
            int searchValue = c - left.get(i);
            // ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ +1
            ans += binarySearch(right, searchValue)+1;
        }

        System.out.println(ans);

        br.close();
    }

    private static int binarySearch(ArrayList<Integer> sum, int target) {
        int left = 0;
        int right = sum.size();

        while (left < right) {
            int mid = (left+right)/2;

            if (sum.get(mid) <= target) {
                left = mid+1;
            } else {
                right = mid;
            }
        }

        return left-1;
    }

    private static void comb(ArrayList<Integer> list, int start, int end, int sum) {
        if (sum > c) return; // ํƒˆ์ถœ ์กฐ๊ฑด

        if (start == end) {
            list.add(sum);
            return;
        }

        // ๋ฌผ๊ฑด์„ ๋„ฃ๋Š” ๊ฒฝ์šฐ
        comb(list, start+1, end, sum+arr[start]);
        // ๋ฌผ๊ฑด์„ ๋„ฃ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
        comb(list, start+1, end, sum);
    }
}

 

์ด๋ถ„ ํƒ์ƒ‰์„ ๊ณต๋ถ€ํ•˜๋˜ ์ค‘์— ์ค‘๊ฐ„์—์„œ ๋งŒ๋‚˜๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ™œ์šฉํ•œ ๋ฌธ์ œ๋Š” ์ฒ˜์Œ ์ ‘ํ•ด์„œ, ๊ฐœ๋…์„ ๊ณต๋ถ€ํ•œ ๋’ค์— ํ’€์–ด๋ณด์•˜๋‹ค.

์ฝ”๋“œ ๊ตฌ์กฐ๋Š” ์ง€๊ธˆ๊นŒ์ง€ ์ž‘์„ฑํ•ด์™”๋˜ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰๊ณผ ์ด๋ถ„ ํƒ์ƒ‰ ์ฝ”๋“œ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์•„, ํฐ ์–ด๋ ค์›€ ์—†์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ตœ๊ทผ ๋“ค์–ด ๋น„์Šทํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋งŒ ํ’€์—ˆ๋Š”๋ฐ ์˜ค๋žœ๋งŒ์— ์ƒˆ๋กœ์šด ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋ผ ์•„์ฃผ ์žฌ๋ฐŒ๊ฒŒ ํ’€์—ˆ๋‹ค ! ๐Ÿ˜Š๐ŸŒŸ