※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 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();
	}
}
728x90

'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

+ Recent posts