반응형
문제
정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.
- X가 3으로 나누어 떨어지면, 3으로 나눈다.
- X가 2로 나누어 떨어지면, 2로 나눈다.
- 1을 뺀다.
정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.
풀이
/3 , /2를 한 수에서 1을 더한 값과, -1를 한 수에서 1을 더한 값 중에
더 작은 값을 dp 배열에 대입한다
코드
#include <stdio.h>
#include <stdlib.h>
int N;
int dp[1000001]; //i의 범위만큼 -> DP함수에서 dp[i+1]로 선언해도 좋음
int min3(int a, int b, int c)
{
if(a<=b && a<=c)
return a;
else if(b<=a && b<=c)
return b;
else if(c<=a && c<=b)
return c;
}
int min2(int a, int b)
{
if(a <= b)
return a;
else
return b;
}
void dfs(int n) //Top-Down 방식으로, 재귀함수를 이용한다
{
if(dp[n] == 0) //필수 조건
{
if(n == 1)
dp[1] = 0;
else if(n == 2)
dp[2] = 1;
else if(n == 3)
dp[3] = 1;
else
{
if(n%3 == 0 && n%2 == 0)
{
dfs(n/3);
dfs(n/2);
dfs(n-1);
dp[n] = min3(dp[n/3], dp[n/2], dp[n-1]) + 1;
}
else if(n%3 == 0)
{
dfs(n/3);
dfs(n-1);
dp[n] = min2(dp[n/3], dp[n-1]) + 1;
}
else if(n%2 == 0)
{
dfs(n/2);
dfs(n-1);
dp[n] = min2(dp[n/2], dp[n-1]) + 1;
}
else
{
dfs(n-1);
dp[n] = dp[n-1] + 1;
}
}
}
}
int main()
{
scanf("%d", &N);
dfs(N);
printf("%d", dp[N]);
return 0;
}
반응형
'etc.' 카테고리의 다른 글
[백준 9095번][C] 1, 2, 3 더하기 (0) | 2020.07.13 |
---|---|
[Java] sort() 메소드 정렬하기 (Arrays, Collections, Comparable, Comparator) (0) | 2020.07.12 |
[백준 1463번][Java] 1로 만들기 (0) | 2020.07.07 |
[Java] 얕은 복사와 비교, 깊은 복사와 비교 (Objects, Arrays 클래스) (0) | 2020.06.29 |
[Java] Arrays 클래스와 Arrays 메소드 정리 (0) | 2020.06.25 |