[백준] 2655 가장높은탑쌓기 - javascript
📌 문제
https://www.acmicpc.net/problem/2655
📌 풀이
let input = require("fs").readFileSync("/dev/stdin").toString().split("\n");
let n = Number(input[0]);
let stones = new Array(n);
for (let i = 0; i < stones.length; i++) {
// stones -> 넓이, 높이, 무게, 그 벽돌의 index
stones[i] = new Array(4);
}
for (let i = 0; i < n; i++) {
stones[i] = input[i + 1].split(" ").map(Number);
stones[i][3] = i + 1;
}
stones.sort((a, b) => a[0] - b[0]); // 밑면넓이 기준 오름차순정렬
// dp[n] = n번째 상자를 쌓았을 때 가능한 최대높이
let dp = new Array(n).fill(0);
// 각 상자의 높이로 초기화
for (let i = 0; i < n; i++) {
dp[i] = stones[i][1];
}
for (let i = 1; i < n; i++) {
for (let j = 0; j < i; j++) {
// 밑면의 넓이는 오름차순이므로 당연히 i가 j보다 크다
// 따라서 무게가 더 큰경우에만 넣을 수 있음
if (stones[j][2] < stones[i][2]) {
dp[i] = Math.max(dp[i], stones[i][1] + dp[j]);
}
}
}
let max = Math.max(...dp);
let answer = []; // 길이가 벽돌의 수
// 쌓은 벽돌 추적하기
for (let i = dp.length - 1; i >= 0; i--) {
if (max == dp[i]) {
answer.push(stones[i][3]);
max -= stones[i][1];
}
}
console.log(answer.length);
answer.reverse();
answer.forEach((a) => console.log(a));
✔ 알고리즘 : DP
✔ stones 배열에는 넓이, 높이, 무게, 그 벽돌의 index정보가 들어가는 2차원 배열
✔ stones를 밑면넓이 기준으로 오름차순 정렬
✔ dp[n] : n개의 상자를 쌓았을 때 가능한 최대높이이고 dp[n]을 n번째 stone의 높이로 초기화한 상태로 dp를 진행
✔ 벽돌을 위에서부터 쌓을 수 있는 조건 : 밑면의 넓이와 무게가 같이 증가해야한다
✔ 이미 밑면넓이기준 오름차순 정렬했으므로 i,j 2중 for문에서 밑면넓이는 볼 필요가 없고 넓이만 보고 i보다 j가 작으면 아래로 쌓을 수 있는 벽돌이 된다. (저의 풀이 방식은 위에서부터 탑을 아래로 쌓는 방식입니다)
✔ 계속 진행하며 dp값 갱신
✔ dp배열의 최댓값이 쌓을 수 있는 탑의 최대높이
✔ dp배열을 역순으로 추적해서 탑이 어떻게 쌓였는지 answer에 저장하고 reverse 하여 출력
✔ 난이도 : 백준 기준 골드3
Author And Source
이 문제에 관하여([백준] 2655 가장높은탑쌓기 - javascript), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ywc8851/백준-2655-가장높은탑쌓기-javascript저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)