https://www.acmicpc.net/problem/1493
1493번: 박스 채우기
세준이는 length × width × height 크기의 박스를 가지고 있다. 그리고 세준이는 이 박스를 큐브를 이용해서 채우려고 한다. 큐브는 정육면체 모양이며, 한 변의 길이는 2의 제곱꼴이다. (1×1×1, 2×2×2,
www.acmicpc.net
오랜만에 포스팅..
솔루션
처음에 정육면체 자르기와 비슷하다 생각하여 DP로 생각해 보았지만, 입력 값이 10^6이라고 해서 dp 배열을 잡기에는 무리가 있다.
그래서 나는 그리디로 한 번 도전 해 보았는데, 다행이게도 맞았습니다를 받았다.
먼저 가장 큰 큐브부터 박스에 넣을 수 있다면, 박스에 넣어주고 남는 공간을 재귀로 호출한다.
만약 박스에 큐브를 채워 넣으면 남는 공간은
l, w, h - CubeSize //채워 놓은 뒤, 위쪽 공간
l - CubeSize, CubeSize, CubeSize //채워 놓고, 높이를 자르고 남는 박스의 앞쪽 공간
l, w-CubeSize, CubeSize //채워놓은 뒤, 박스의 남은 폭 공간.
이렇게 세 개를 호출하면 된다.
해당하는 사이즈의 큐브 개수가 없거나, 너비나 폭 높이가 큐브 사이즈보다 작으면 더 작은 큐브로 바꿔서 재귀를 계속해서 호출하면 된다.
코드
#include <iostream>
#include <vector>
using namespace std;
struct pa {
int size, num;
};
int L, W, H;
vector<pa>V;
int N;
int cnt = 0;
int solve(int l, int w, int h, int idx) {
if (idx == -1) {
return -1;
}
if (l == 0 || w == 0 || h == 0) return 0;
int cur = 1 << V[idx].size;
int dest = min(l, min(w, h));
if (cur > dest || V[idx].num == 0) {
return solve(l, w, h, idx - 1);
}
else {
int ref = 0;
V[idx].num--;
cnt++;
ref = min(solve(l, w, h - cur, idx), ref); //높이 쪽으로 남는 공간
ref = min(solve(l - cur, cur, cur, idx),ref); //박스의 lengh 쪽으로 남는 공간
ref = min(solve(l, w - cur, cur, idx),ref); //박스의 폭으로 남는공간
return ref;
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> L >> W >> H;
cin >> N;
for (int i = 0; i < N; i++) {
pa t;
cin >> t.size >> t.num;
V.push_back(t);
}
solve(L, W, H, V.size() - 1) == -1 ? cnt = -1 : cnt = cnt;
cout << cnt << '\n';
}
'백준' 카테고리의 다른 글
C++[백준]11025번 요세푸스 문제 3 (0) | 2023.10.30 |
---|---|
C++[백준]1727번 커플 만들기 (1) | 2023.10.25 |
C++[백준]20529 가장 가까운 세 사람의 심리적 거리 (0) | 2023.07.11 |
C++[백준]20303번 할로윈의 양아치 (0) | 2023.07.04 |
C++[백준]1915번 가장 큰 정사각형 (0) | 2023.06.23 |