문제 링크: https://www.acmicpc.net/problem/18111
깎거나, 쌓거나 둘 중 하나를 하면 됩니다.
깎는데는 2초, 쌓는데는 1초가 걸리니까 최대한 쌓는 방향으로 하면 되겠죠.
그런데 인벤토리에 있는 블록 수가 주어지고 이 블록만큼만 사용해 쌓을 수 있습니다.
[최소높이, 최대높이]로 모든 높이에 대해 쌓거나 깎거나 할 수 있는 경우에만 <걸린시간, 높이>를 저장해서 가장 적게 걸린 시간 중 가장 높은 것을 갖고오면 됩니다. 즉 브루트포스죠
유의할 점은 깎은 블록을 쌓는 데 쓸 수 있다는 점이 있겠습니다.
// 18111
#pragma GCC optimize ("Ofast")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int plane[500][500];
int n, m, b;
int cost(int from, int to) {
if (from < to) // 쌓기
return to - from;
else // 부수기
return 2 * (from - to);
}
// 가능한 경우, 걸리는 시간 반환
// 불가능한 경우, -1
int possible(int target_height, int blocks) {
int elapsed_time = 0;
int needed_blocks = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
elapsed_time += cost(plane[i][j], target_height);
needed_blocks += target_height - plane[i][j];
}
}
return (needed_blocks <= blocks ? elapsed_time : -1);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m >> b;
int max_height = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> plane[i][j];
max_height = max(max_height, plane[i][j]);
}
}
vector<pair<int, int>> ans;
for (int i = 0; i <= max_height; ++i) {
int p = possible(i, b);
if (p != -1) {
ans.emplace_back(p, -i);
}
}
sort(ans.begin(), ans.end());
cout << ans[0].first << ' ' << -ans[0].second << '\n';
return 0;
}
지금 보니 구현이 좀 비효율적이네요. 그래도 입력 크기가 작아 푸는데 문제는 없습니다
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 18119: 단어 암기 (0) | 2020.06.21 |
---|---|
[백준][C++] 17081: RPG Extreme (4) | 2020.06.16 |
[백준][C++] 2293: 동전 1 (0) | 2020.06.14 |
[백준][C++] 1259: 팰린드롬수 (0) | 2020.06.13 |
[백준][C++] 1620: 나는야 포켓몬 마스터 이다솜 (0) | 2020.06.12 |