본문 바로가기
Algorithm Trainning/백준 알고리즘(BEAKJOON)

백준 : 1463번, 1로 만들기

by newbie22 2020. 12. 17.

문제 주소 : www.acmicpc.net/problem/1463

정답 비율 : 32.217% (2020.12.17 11:59 기준)

 

1463번: 1로 만들기

첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.

www.acmicpc.net

 

 

문제 요약 : 정수 n에 대하여 다음 3가지의 연산을 할 수 있습니다.

1. 3의 배수이면 3으로 나눌 수 있습니다.

2. 2의 배수이면 2로 나눌 수 있습니다.

3. 그냥 1을 뺀다.

 

-> 어떤 수가 주어질 때 위 3가지의 연산의 사용 횟수를 최소로 하여 1로 만드면 됩니다.

-> n의 범위는 다음과 같습니다. 1 <= n <= 1000000

 

문제 풀이

DP이라는 느낌을 받으면 간단한 DP문제입니다. 

점화식은 다음과 같습니다.

 

0. dp[0] = -1, n >= 1 일 때 다음이 성립합니다.

1. dp[n] = 1 + dp[n - 1] (조건 X)

2. dp[n] = 1 + dp[n / 2] (조건 : 2의 배수)

3. dp[n] = 1 + dp[n / 3] (조건 : 3의 배수)

 

여기서 여러 개의 식을 만족할 때에는 그중 최소 값을 저장합니다.

 

코드는 다음과 같습니다.

 

C99

#include<stdio.h>

int arr[1000001];

int main(void)
{
    int n, i = -1;
    
    scanf("%d", &n);
    
    arr[0] = -1
    
    for(i = 1; i <= n; i++)
    {
    	arr[i] = 1 + arr[i - 1];
    	
    	if(i % 2 == 0 && arr[i] > 1 + arr[i / 2])
    		arr[i] = arr[i / 2] + 1;
    		
    	if(i % 3 == 0 && arr[i] > 1 + arr[i / 3])
    		arr[i] = arr[i / 3] + 1;
	}
    
    printf("%d\n",arr[n]);
    
    return 0;
}

 

Python3

#solve 1463    

n = int(input())

dp = [-1]

for i in range(1, n + 1) :
    if i % 6 == 0 :
        dp.append(min(1 + dp[i - 1], 1 + dp[int(i / 2)], 1 + dp[int(i / 3)]))
    elif i % 3 == 0 :
        dp.append(min(1 + dp[i - 1], 1 + dp[int(i / 3)]))
    elif i % 2 == 0 :
        dp.append(min(1 + dp[i - 1], 1 + dp[int(i / 2)]))
    else :
        dp.append(1 + dp[i - 1])
        
print(dp[n])

 

-> 처음 문제를 접했을 때 BFS로 모든 경우의 수를 조사해야 하나 하고 코드를 짜는 중에 DP문제임을 깨달았습니다.

'Algorithm Trainning > 백준 알고리즘(BEAKJOON)' 카테고리의 다른 글

백준 : 2493번, 탑  (0) 2021.02.11
백준 : 1012번, 유기농 배추  (0) 2020.12.22
백준 : 1929번, 소수 구하기  (0) 2020.12.16
백준 : 2798번, 블랙잭  (0) 2020.12.16
백준 : 10250번, ACM 호텔  (0) 2020.12.15