본문 바로가기
알고리즘 이전/DP

가장 높은 탑 쌓기(LIS)

by hoshi03 2023. 9. 9.

밑면이 정사각형인 직육면체 벽돌들을 사용하여 탑을 쌓고자 한다. 탑은 벽돌을 한 개씩 아래에서 위로 쌓으면서 만들어 간다.

아래의 조건을 만족하면서 가장 높은 탑을 쌓을 수 있는 프로그램을 작성하시오.

(조건1) 벽돌은 회전시킬 수 없다. 즉, 옆면을 밑면으로 사용할 수 없다.

(조건2) 밑면의 넓이가 같은 벽돌은 없으며, 또한 무게가 같은 벽돌도 없다.

(조건3) 벽돌들의 높이는 같을 수도 있다.

(조건4) 탑을 쌓을 때 밑면이 좁은 벽돌 위에 밑면이 넓은 벽돌은 놓을 수 없다.

(조건5) 무게가 무거운 벽돌을 무게가 가벼운 벽돌 위에 놓을 수 없다.

 

입력

5
25 3 4
4 4 6
9 2 3
16 2 5
1 5 2
출력

10

 

최대 부분 증가수열을 응용한 문제, 무게와 넓이 중 하나를 잡아서 내림차순으로 정렬하면 최대 부분 증가수열과 거의 같은 문제가 된다

 

넓이를 기준으로 오름차순 정렬한 후 i번째 블록이 맨 위에 있을 때 dy[i] = dy[기존까지 블록으로 쌓은 높이 최대] + arr[i] 블록의 높이가 되게 해서 최대값을 찾는다

 

 

import java.util.*;

class block implements Comparable<block>{
    int size;
    int height;
    int weight;
    block(int size, int height, int weight){
        this.size = size;
        this.height = height;
        this.weight = weight;
    }

    @Override
    public int compareTo(block o) {
        return o.size - this.size;
    }
}


class Main{

    static int[] dy;
    public int Solution(ArrayList<block> arr){
       int ans = 0;
       dy = new int[arr.size()];
        //맨 앞 = 제일 무거운 벽돌을 위에 올렸을때 다른 벽돌은 못올라감, 인덱스는 자기의 높이를 가짐
       dy[0] = arr.get(0).height;
        for (int i = 1; i < arr.size(); i++){
            int max = 0;
            for (int j = i -1; j >= 0; j--){
                //i번째 벽돌을 제일 위에 놓았을 때 탑의 높이
                if (arr.get(i).weight < arr.get(j).weight && dy[j] > max) {
                    max = dy[j];
                }
            }
            dy[i] = max + arr.get(i).height;
            ans = Integer.max(dy[i], ans);
        }
        return ans;
    }

    public static void main(String[] args) {
        Main T = new Main();
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        ArrayList<block> arr = new ArrayList<>();
        for (int i = 0; i <n; i++) arr.add(new block(in.nextInt(), in.nextInt(), in.nextInt()));
        Collections.sort(arr);
        System.out.println(T.Solution(arr));
    }
}

 

 

'알고리즘 이전 > DP' 카테고리의 다른 글

최대점수 구하기(냅색)  (0) 2023.09.11
동전교환(냅색)  (0) 2023.09.10
최대 부분 증가수열(LIS)  (1) 2023.09.09
계단 오르기, 돌다리 건너기  (0) 2023.09.09