알고리즘

가장 높은 탑 쌓기(Dynamic Programing)

odong2 2024. 4. 23. 15:20

가장 높은 탑 쌓기

 

 

 

코드

package dynamic;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

/**
 * 가장 높은 탑 쌓기(LIS 응용)
 */
public class Dynamic3 {
    // 벽돌 클래스
    static class Brick implements Comparable<Brick> {

        int area;   // 넓이
        int height; // 높이
        int weight; // 무게

        Brick(int area, int height, int weight) {
            this.area = area;
            this.height = height;
            this.weight = weight;
        }

        @Override
        public int compareTo(Brick o) {
            return o.area - this.area; // 넓이 내림차순 정렬
        }
    }

    static int[] dy; // 쌓은 벽돌의 높이를 누적

    static int solution(List<Brick> list) {
        int answer = 0;

        Collections.sort(list); // 넓이에 대해 내림차순 정렬

        dy[0] = list.get(0).height; // 첫 번째 벽돌의 높이로 초기화
        answer = dy[0]; // 첫 번째 벽돌은 무조건 쌓으므로 answer 초기화

        for (int i = 1; i < list.size(); i++) {
            int maxHeight = 0;

            for (int j = i - 1; j >= 0; j--) {
                if (list.get(j).weight > list.get(i).weight && dy[j] > maxHeight) {
                    maxHeight = dy[j];
                }
            }
            // 제일 높게 쌓인 벽돌 위에 i 번째 벽돌 높이 더하기
            dy[i] = maxHeight + list.get(i).height;

            answer = Math.max(answer, dy[i]);
        }


        return answer;
    }


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

        dy = new int[N];
        List<Brick> list = new ArrayList<>();

        StringTokenizer st;

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());

            int area = Integer.parseInt(st.nextToken());
            int height  = Integer.parseInt(st.nextToken());
            int weight = Integer.parseInt(st.nextToken());

            list.add(new Brick(area, height, weight));
        }

        System.out.println(solution(list));
    }
}

 

풀이

1. 벽돌 클래스를 만들어 정렬 기준을 넓이 내림차순으로 한다.

2. dy[ j ] 번째 벽돌이 dy [ i ] 번 째 벽돌 보다 무게가 적고,  dy[ j ] 번째 중 높이가 가장 높게 쌓인(maxHeight) 벽돌 위에 i 번째 벽돌의 높이를 더해서 초기화한다.

 

이번 문제는 최대 부분 증가수열 문제와 유사한 구조로 풀이법은 동일하다.