PS
BOJ - 1463번 1로 만들기
식용감자
2020. 9. 3. 14:21
https://www.acmicpc.net/problem/1463
1463번: 1로 만들기
첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.
www.acmicpc.net
정수가 주어졌을 때 1을 만드는 연산의 최소횟수를 구하는 문제다.
연산의 종류는 다음과 같다.
- 3의 배수면 3으로 나눌 수 있다.
- 2의 배수면 2로 나눌 수 있다.
- 1을 뺄 수 있다.
간단하게 생각할 수 있다.
어떤 수 N에 대해서 1을 빼거나 2로 나누거나 3으로 나누거나 해보자.
min_1 = N-1
div_2 = N/2
div_3 = N/3
이라고 생각하면 결국에 또 min_1도 위와같은 방식으로 1로 만들어야 할거고 div_2도, div_3도 1로 만들어야 한다.
작은 수부터 미리 계산했었다면
min(min_1을 1로 만드는 횟수, div_2를 1로 만드는 횟수, div_3을 1로 만드는 횟수) + 1
이 N을 1로 만드는 최소 횟수일 것이다.
/* BOJ - 1463번 1로 만들기 문제 다시풀기 */
#include <stdio.h>
int DP[1000001];
// 초기화 함수
void init() {
for (int i = 0; i < 1000001; i++) DP[i] = 0;
}
// 계산 함수
void cal() {
int div_3, div_2, min_1, i, min;
for (i = 2; i < 1000001; i++) {
min_1 = DP[i - 1] + 1;
if (i % 2 == 0) div_2 = DP[i / 2] + 1;
else div_2 = min_1 + 1;
if (i % 3 == 0) div_3 = DP[i / 3] + 1;
else div_3 = min_1 + 1;
min = min_1;
if (min > div_2) min = div_2;
if (min > div_3) min = div_3;
DP[i] = min;
}
}
int main()
{
int N;
scanf("%d", &N);
init();
cal();
printf("%d\n", DP[N]);
return 0;
}