⛔ 단순히 기록용 입니다... 어떻게 풀었는가 생각도 다시 해보고 그러니까 아마도 도움은 안되실 것 같습니다.
정사면체가 하나씩 증가하는 공식과 그리고 그 크기만큼 정사면체를 만들 수 있다면? 그건 하나의 정사면체가 된다. 우리는 최소의 정사면체를 만들어야 하기 때문에, 최대한 정사면체를 크게 만들고 나머지 값으로 최소한의 정사면체를 만들어야하는 문제를 갖고 있습니다.
그래서 우리는 일단 개수따라 정사면체를 만들 수 있는지 알아야 한다. 그에 따른 공식은 아래의 코드와 같다. 그리고 이에 따라서 그 개수로 정사면체를 만들 수 있는 것이 된다.
아래는 점화식이다. 추후에 좀 더 자세히 작성을 해봐야 겠다.. 너무 피곤햇
일단 우리는 n개로 정사면체를 만들 수 있다는 것을 vector안에 차례로 추가해주었다.
그 값을 시작으로 ! 왜 이 값을 시작으로 할까? 이 값은 어쨌든 지금 당장 하나를 만들 수 있는 값이기 때문이다. 이어서 그 값을 시작으로 우리가 제시한 n개까지 어떻게 최소한의 값을 구할 수 있을까?
시작부터 차례대로, 시작값의 개수와 시작값에서 현재 크기를 제외한 값 + 1(이미 하나를 만들었기에, 현재 크기를 제외했기에) 그렇게 해서 최소값을 구하면 된다. 그렇다면 초기화로 1e9로 삽입해야겠다.
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAX 300001
using namespace std;
int n;
long long dp[MAX];
vector<int> v;
int main() {
cin >> n;
for(int i = 1; ; i++){
int num = i * (i + 1) * (i + 2) / 6; // 50000
if(num > MAX) break;
v.push_back(num);
}
fill(dp, dp + MAX, 1e9);
for(int i = 0; i < v.size(); i++){
dp[v[i]] = 1;
}
for(int i = 0; i < v.size(); i++){
for(int j = v[i]; j <= n; j++){
dp[j] = min(dp[j], dp[j - v[i]] + 1);
}
}
cout << dp[n];
return 0;
}
'PS > BaekJoon' 카테고리의 다른 글
[C++/31937] 로그프레소 마에스트로 (1) | 2024.06.13 |
---|---|
[C++/1347] 미로 만들기 (1) | 2024.06.10 |
[C++/30024] 옥수수 밭 (0) | 2024.05.27 |
[C++/28432] 끝말잇기 (0) | 2024.05.22 |
[C++/1527] 금민수의 개수 (0) | 2024.05.21 |