문제 출처
1. 문제설명
- 정수
X
를 1로 만드는 최소한의 방법과 그 수를 출력하라
- 사용 가능한 연산
X
가 3으로 나누어 떨어지면 3으로 나눈다.
X
가 2로 나누어 떨어지면 2로 나눈다.
- 1을 뺀다.
2. 알고리즘 설계
- 시간 제한이 0.5초이므로, DP 외에 떠오른 방법이 없다.
- 1을 빼준 값으로 DP 배열을 초기화 시킨다.
- 기존 연산 수, 2로 나눴을 때의 연산 수, 3으로 나눴을 때 연산 수 중 작은 값으로 갱신
- 위치를 기억해야 하므로, 위치도 각 연산에 맞게 설정한다.
3. 전체 코드
#include <bits/stdc++.h>
using namespace std;
const int SZ = 1000001;
int n, DP[SZ], pre[SZ];
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
DP[1] = 0;
for(int i=2; i<=n; i++) {
DP[i] = DP[i-1] + 1;
pre[i] = i-1;
if(i%2 == 0 && DP[i] > DP[i/2]) {
DP[i] = DP[i/2] + 1;
pre[i] = i/2;
}
if(i%3 == 0 && DP[i] > DP[i/3]) {
DP[i] = DP[i/3] + 1;
pre[i] = i/3;
}
}
cout << DP[n] << '\n';
int idx = n;
while(true) {
cout << idx << ' ';
if(idx == 1) break;
idx = pre[idx];
}
return 0;
}