Link
https://www.acmicpc.net/problem/25378
Detail
처음에는 탑다운방식으로 해결하려고 했으나, 해당 방식이 메모리 부하를 일으켜 Tabulation으로 그 방법을 수정하였다.
핵심 아이디어는 다음과 같다.
- 모든 조약돌은 최대 N회만에 전부 회수가 가능하다.
- 두 영역의 조약돌을 회수하여 동시에 0으로 만들 수 있을경우, 그 횟수를 줄일 수 있다.
따라서 해답 로직은 다음과 같다.
- i번째 돌을 회수할 때, i - 1번째 돌이 존재할 수 있는 모든 경우의 수를 연산한다.
- 연산해서 완전히 0으로 만들 수 있을 경우, 해당 경우를 채택한다.
Code
#include <iostream>
#include <vector>
using namespace std;
int solve(const vector<int>& stones) {
vector<vector<int>> remains(stones.size());
for (int i = 0; i < stones.size(); i++){
remains[i].push_back(stones[i]);
}
int answer = (int)stones.size();
for (int i = 1; i < stones.size(); i++){
for (auto st : remains[i - 1]) {
if (stones[i] > st) {
remains[i].push_back(stones[i] - st);
}
else if (stones[i] == st) {
remains[i].clear();
answer--;
break;
}
}
}
return answer;
}
int main(){
int n;
cin >> n;
vector<int> stones(n);
for (int i = 0; i < n; i++){
cin >> stones[i];
}
cout << solve(stones) << "\n";
return 0;
}