※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 2655번 문제인 가장높은탑쌓기이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/2655
2655번: 가장높은탑쌓기
첫째 줄에는 입력될 벽돌의 수가 주어진다. 입력으로 주어지는 벽돌의 수는 최대 100개이다. 둘째 줄부터는 각 줄에 한 개의 벽돌에 관한 정보인 벽돌 밑면의 넓이, 벽돌의 높이 그리고 무게가 차
www.acmicpc.net
이 문제에서는 만들 수 있는 가장 높은 탑을 쌓을 때, 그 탑을 구성하는 벽돌의 개수와 그 순서를 탑의 위에서부터 출력하는 문제이다.
글쓴이는 위상정렬을 이용하여 문제를 해결하였다.
벽돌이 최대 100개이므로, 두개의 벽돌을 고르는 모든 경우에 대하여 한 벽돌이 다른 벽돌 위에 올라갈 수 있는지를 판단해 가능하다면 directed edge를 긋는 방식으로 방향그래프를 만들 수 있다. 이 그래프는 DAG가 될 수밖에 없으며, 이 그래프를 이용하여 위상정렬을 하면 문제를 해결할 수 있다.
이 탑을 구성하는 벽돌은 위상정렬 과정에서 각 노드로 도달한 경로들을 기록한 뒤 역추적하는 것으로 구할 수 있다.
굳이 그래프를 만들어 위상정렬을 하지 않더라도, 한 가지 기준으로 먼저 정렬을 한 뒤 단순히 DP를 하는 방식으로도 문제를 해결할 수 있을 것으로 보인다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int arr[101][3]; // 0:넓이, 1:무게, 2:높이
int cnt[101];
vector<int> G[101];
queue<int> que;
int height[101];
int parent[101];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N; cin >> N;
for (int i = 1; i <= N; i++) {
cin >> arr[i][0] >> arr[i][2] >> arr[i][1];
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j < i; j++) {
if (arr[i][0] > arr[j][0] && arr[i][1] > arr[j][1]) {
G[i].push_back(j);
cnt[j]++;
}
else if (arr[i][0] < arr[j][0] && arr[i][1] < arr[j][1]) {
G[j].push_back(i);
cnt[i]++;
}
}
}
for (int i = 1; i <= N; i++) {
if (!cnt[i]) que.push(i);
}
while (!que.empty()) {
int current = que.front(); que.pop();
height[current] += arr[current][2];
for (auto node : G[current]) {
if (height[node] < height[current]) {
height[node] = height[current];
parent[node] = current;
}
cnt[node]--;
if (cnt[node] == 0) que.push(node);
}
}
int mxheight = 0;
int mxidx;
for (int i = 1; i <= N; i++) {
if (mxheight < height[i]) {
mxheight = height[i];
mxidx = i;
}
}
que.push(mxidx);
while (parent[mxidx] > 0) {
mxidx = parent[mxidx];
que.push(mxidx);
}
cout << que.size() << '\n';
while (!que.empty()) {
cout << que.front() << '\n';
que.pop();
}
}
'BOJ' 카테고리의 다른 글
[BOJ 11238 // C++] Fibo (0) | 2021.08.26 |
---|---|
[BOJ 17080 // C++] 결함 게임 (0) | 2021.08.25 |
[BOJ 1932 // C++] 정수 삼각형 (0) | 2021.08.23 |
[BOJ 2631 // C++] 줄세우기 (0) | 2021.08.22 |
[BOJ 1695 // C++] 팰린드롬 만들기 (0) | 2021.08.21 |