b11066. 파일 합치기

2025. 1. 10. 13:57·Algorithm & Data Structures/BOJ

 

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

 

 

 

이 문제는 파일을 합치는 문제로써 주어진 파일들을 순서대로 합치면서

최소 비용을 계산하는 것이다.

 

처음에는 이 문제를 보고 그리디 알고리즘으로 풀어야겠다는 생각이 들었다.

그래서 최소힙(Min-Heap)을 사용해 가장 작은 두 파일을 계속 합치는 방식으로 접근했다.

그러나 결과적으로 이 방식은 문제를 제대로 해결하지 못했다.

파일의 순서를 고려하지 않았기 때문이다.

Heap을 활용한 방식은 각 단계에서 비용을 최소화하려고 하지만,

이는 부분적으로만 최적화될 뿐,

전체 비용이 최소가 되는 것을 보장하지 않는다.

또한, 문제의 조건에서 "파일은 주어진 순서대로 합쳐야 한다"는 점을 간과했다.

이 제약을 무시하면 잘못된 결과를 도출할 수밖에 없다.

직접 예제 데이터를 입력해 본 결과,

틀린 답이 나왔고, 이에 대한 원인을 분석하면서 접근 방식을 다시 생각하게 되었다.

 

문제를 다시 들여다보니,

파일의 순서를 유지하며 최소 비용을 계산하려면

**동적 계획법(DP)**을 사용하는 것이 적합했다.

DP는 특정 구간의 최적 값을 계산하고 이를 점진적으로 확장해

전체 문제를 해결하는 방식이다.

 

이 문제에서는 DP와 함께 누적 합(prefix sum)을 활용해

구간 합을 빠르게 계산하도록 설계할 수 있었다.

해결 과정에서 가장 중요한 점은 dp[i][j]를 정의하는 것이었다.

여기서 dp[i][j]는 i번 파일부터 j번 파일까지를 합치는 데 필요한 최소 비용을 의미한다.

이 값을 구하기 위해 구간을 나누는 기준점 k를 설정하고,

dp[i][j]를 이전 결과들을 기반으로 계산했다.

구간의 총 크기는 누적 합을 사용해 효율적으로 계산했으며,

이렇게 채워진 DP 테이블의 최종 값인 dp[0][N-1]이 우리가 찾는 최소 비용이다.

잘못된 풀이와 올바른 풀이를 비교하며,

문제의 조건을 정확히 이해하는 것이 얼마나 중요한지 다시 한 번 깨달았다.

처음에는 직관적으로 접근해도 맞는 풀이처럼 보였지만,

조건을 무시한 접근은 결국 실패로 이어졌다.

이를 통해 문제를 푸는 데 있어 제약 조건을 면밀히 분석하고,

그에 맞는 알고리즘을 선택하는 것이 얼마나 중요한지 배울 수 있었다.

 

 

import java.io.*;
import java.util.Arrays;
public class Main {

    static int T, N;
    static int[][] dp;
    static int[] prefixSum,fileSize;

    private static void init(BufferedReader br) throws IOException {
        N = Integer.parseInt(br.readLine());
        fileSize = Arrays.stream(br.readLine().split(" "))
                .mapToInt(Integer::parseInt)
                .toArray();
        dp = new int[N][N];
        prefixSum = new int[N];

        prefixSum[0] = fileSize[0];
        for (int i = 1; i < N; i++)
            prefixSum[i] = prefixSum[i-1] + fileSize[i];
    }

    private static void logic() {
        for (int d = 1 ; d < N; d++){
            for (int i = 0; i < N - d; i++) {
                int j = i + d;
                dp[i][j] = Integer.MAX_VALUE;

                for (int k = i ; k < j ; k++){
                    int cost = dp[i][k]+dp[k+1][j]+(prefixSum[j] - (i > 0 ? prefixSum[i-1]:0));
                    dp[i][j] = Math.min(dp[i][j],cost);
                }
            }
        }
        System.out.println(dp[0][N-1]);
    }
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        T = Integer.parseInt(br.readLine());
        for (int t = 0; t < T ; t++){
            init(br);
            logic();
        }
    }
}

// Heap을 이용하여 순서를 고려하지않은 잘못된 풀이

//public class Main {
//
//    static int T, N, answer;
//
//    static PriorityQueue<Integer> pq;
//
//    private static void logic(){
//        while(pq.size()>=2){
//            int sum = pq.poll()+pq.poll();
//            answer += sum;
//            pq.add(sum);
//        }
//    }
//
//    private static void init(BufferedReader br) throws IOException {
//
//        pq = new PriorityQueue<>();
//        answer = 0;
//        N = Integer.parseInt(br.readLine());
//        StringTokenizer st = new StringTokenizer(br.readLine());
//
//        while(st.hasMoreTokens())
//            pq.add(Integer.parseInt(st.nextToken()));
//
//    }
//
//    public static void main(String[] args) throws IOException {
//
//        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        T = Integer.parseInt(br.readLine());
//        for (int t = 0; t < T ; t++){
//            init(br);
//            logic();
//            System.out.println(answer);
//        }
//    }
//
//
//}

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

b2629. 양팔저울  (0) 2025.01.17
b11049. 행렬 곱셈 순서  (0) 2025.01.13
b1300. K번째 수  (0) 2025.01.08
b6549. 히스토그램에서 가장 큰 직사각형  (0) 2025.01.06
b12100. 2048(Easy)  (0) 2025.01.03
'Algorithm & Data Structures/BOJ' 카테고리의 다른 글
  • b2629. 양팔저울
  • b11049. 행렬 곱셈 순서
  • b1300. K번째 수
  • b6549. 히스토그램에서 가장 큰 직사각형
Geisha
Geisha
개발 일기
  • Geisha
    Geisha
    Geisha
  • 전체
    오늘
    어제
    • 분류 전체보기 (326)
      • Algorithm & Data Structures (246)
        • BOJ (104)
        • SWEA (1)
        • Programers (137)
        • Data Structures (3)
      • DB (27)
        • SQL (21)
        • RDBMS (2)
      • Java (1)
        • Class (1)
      • Spring (5)
        • Spring MVC (1)
        • Annotations (1)
      • CS (36)
        • 운영체제 (13)
        • 네트워크 (5)
      • Tool (6)
        • Git (5)
        • AWS (1)
      • Project (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    PriorityQueue
    SQL
    Dijkstra
    후위순회
    경로압축
    programmers
    unionfind
    백준
    유니온파인드
    Stack
    이분탐색
    algorithm
    골드
    Union-Find
    프로그래머스
    Java
    전위순회
    BFS
    동적계획법
    DynamicProgramming
    baekjoon
    백트래킹
    스택
    dfs
    알고리즘
    dp
    binarySearch
    구현
    다익스트라
    투포인터
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Geisha
b11066. 파일 합치기
상단으로

티스토리툴바