Algorithm/BOJ

[백준 - 1026] 보물 - Java

ikjo 2022. 8. 2. 02:34

문제 설명

 

 

1026번: 보물

첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거

www.acmicpc.net

 

접근 방법

해당 문제는 그리디 알고리즘 기법을 이용하여 해결할 수 있었습니다.

 

사실 이 문제를 처음 봤을 때 시간 제한이 2초이길래 A에 있는 N개의 수를 재배열할 수 있는 모든 경우의 수에 대해 완전 탐색하여 구해도 되겠다는 생각을 했었습니다. 그리하여 백트래킹을 통해 각각의 경우에 수에 대해 최솟값을 구하도록 했으나, 결과는 시간 초과였습니다. 😅

 

N은 50보다 작거나 같은 자연수이긴 하지만 이들을 순열로 재배열한다는 것은 50!라는 엄청난 수에 대해 탐색하는 것이기 때문에 매우 비효율적인 방법이었습니다.

 

그리하여 접근 방법을 달리하여 어떻게 하면 최솟값을 구할 수 있을지 생각해봤는데, 좀만 생각해보니 A를 오름차순으로 정렬하고 B를 내림차순으로 정렬한 이후에 각각의 요소별로 곱해주고 누적하여 더한다면 그 값이 최솟값이었습니다. 개인적인 직관으로 따져보았을 때는 곱셈 연산 시 B의 최댓값을 A의 최솟값으로 무마시켜 최대한 값을 억제시키 수 있겠다 생각했습니다.

 

전체 소스 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[] a = new int[n];
        Integer[] b = new Integer[n];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(st.nextToken());
        }
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            b[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(a);
        Arrays.sort(b, Comparator.reverseOrder());

        int result = 0;
        for (int i = 0; i < n; i++) {
            result += a[i] * b[i];
        }

        System.out.println(result);
    }
}

 

(번외) 백트래킹을 통한 풀이 - 시간 초과

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;

class Main {

    static int n, result = 500000;
    static Stack<Integer> numbers = new Stack<>();
    static int[] a, b;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        a = new int[n];
        b = new int[n];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(st.nextToken());
        }
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            b[i] = Integer.parseInt(st.nextToken());
        }

        boolean[] visited = new boolean[n];
        arrange(0, visited);

        System.out.println(result);
    }

    private static void arrange(int depth, boolean[] visited) {
        if (depth == n) {
            result = Math.min(result, getSum());
            return;
        }

        for (int i = 0; i < n; i++) {
            if (!visited[i]) {
                visited[i] = true;
                numbers.push(a[i]);
                arrange(depth + 1, visited);
                visited[i] = false;
                numbers.pop();
            }
        }
    }

    private static int getSum() {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += numbers.get(i) * b[i];
        }
        return sum;
    }
}

 

참고자료

'Algorithm > BOJ' 카테고리의 다른 글

[백준 - 2470] 두 용액 - Java  (0) 2022.08.02
[백준 - 1874] 스택 수열 - Java  (0) 2022.08.02
[백준 - 2580] 스도쿠 - Java  (0) 2022.07.31
[백준 - 2096] 내려가기 - Java  (0) 2022.07.28
[백준 - 1405] 미친 로봇 - Java  (0) 2022.07.25