본문 바로가기
C C++/C C++ 백준

C언어 백준 1463번 1로 만들기

by Go! Jake 2022. 5. 28.

문제

정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.

  1. X가 3으로 나누어 떨어지면, 3으로 나눈다.
  2. X가 2로 나누어 떨어지면, 2로 나눈다.
  3. 1을 뺀다.

정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.

문제 풀이

#include <stdio.h>
#include <string.h>
#define MIN(a,b) (a<b? a:b)

void solution(int n);
int arr[1000001]={0,};
int num;

int main(void)
{
	scanf("%d",&num);
	solution(num);
	return 0;
}

void solution (int n)
{
	int i;
	arr[0]=0;
	arr[1]=0;
	int temp;
	
	for (i=2; i<n+1; i++)
	{
		arr[i]=arr[i-1]+1;
		if (i%3==0)
		{
			temp=arr[i/3]+1;
			arr[i]=MIN(temp,arr[i]);
		}
		if (i%2==0)
		{
			temp=arr[i/2]+1;
			arr[i]=MIN(temp,arr[i]);
		}
	}
	printf("%d",arr[n]);
}

DP에서 중요한 부분은 '배열'로 푼다는 점과 '배열의 인덱스와 배열이 가진 값'을 어떻게 설정할 것인지였습니다.

배열 인덱스인 i는 해당되는 숫자이고, arr[i]가 담은 값은 연산 횟수가 됩니다.

- 연산 횟수의 minimum 값을 배열 값에 덮어쓰기

- 식 세우기 (e.g. temp=arr[i/2]+1 ==> 'i번 째 값이 2로 나눠지는 경우 arr[i/2]대비 1 증가한 값을 가지고 있다.')

댓글