본문 바로가기

알고리즘

백준)1로 만들기

 

https://www.acmicpc.net/problem/1463

 

1463번: 1로 만들기

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

www.acmicpc.net

 

a = int(input())

dp = [0] * (a + 1)


for i in range(2,a+1):
  dp[i] = dp[i-1] + 1
  if i % 2 ==0:
    dp[i] = min(dp[i], dp[i // 2] + 1)
  if i % 3 == 0:
    dp[i] = min(dp[i], dp[i // 3] + 1)

print(dp[a])

 

 

DP문제이다.

처음엔 dp인 것을 알았으나 도무지 풀 방법이 떠오르지 않아 그리디로 풀어보려했다.

그러나 여느 dp문제가 그렇듯이 이 문제 또한 그리디로 풀 수가 없다.

한 예로 

input이 10인 경우를 살펴보자

10인 경우 그리디로 풀면

10 // 2 -> 5 

5 -1 -> 4

4 // 2 - > 2

2 // 2. > 1

답은 4가 나오는 반면, 실제 정답은,

10 - 1 -> 9

9 // 3 -> 3

3 // 3 -> 1

무려 3이 나온다.

 

때문에 도무지 풀 방법이 떠오르지가 않았다.

DFS로 문제를 풀어보려 시도했으나 실패했다.

그래서 검색을 이용했다.

문제를 이해하는데엔 좀 애를 먹었다.

 

문제는 상당히 쉬웠다.

우선 반복문을 돌며 dp 리스트에 해당숫자 인덱스에 값을 넣는다.

즉 dp[i]번째에 dp[i-1] +1 값을 집어 넣는다.

여기서 잠깐 애를 먹었다. 왜 +1을 더하는지.

+1을 더하는 이유는, 해당 i번째는 i-1 번째에서 +1을 한 값이기 때문이다.

즉, i가 5라고 생각했을 때,

i-1. 즉 4의 값은 2가 나온다.

여기서 4는

4 // 2 -> 2

2 // 2 -> 1

여기서 5는 -1을 한 번 더 하므로 i-1 의 값에 +1을 해준다.

하지만 여기서 i가 3 또는 2로 나뉜다면 말은 좀 달라진다.

예를들어 i가 9일때, 

9 // 3 -> 3

3 // 3. > 1

dp[9]는 2가 된다

또한 i가 12일 때는 

dp[12 - 1] 의 값인 4에서 +1 한 값인 5가 나와야 정상이지만,

실제 정답은 

12 // 3 -> 4

4 // 2 -> 2

2 // 2 -> 1

3이 된다.

때문에 우선 해당 i번째에 -1을 한 값에 +1을 한 다음

i가 3의 배수인지, 2의 배수인지 확인해준다.

만일 3의 배수인 경우, i값을 3으로 나눈 값

즉 dp[i // 3]값에 +1 (한 번 더 3을 나눠야 하므로 +1을 해야한다)

값과 dp[i-1] + 1값을 비교해 최소값을 dp[i]에 넣어주면 된다.

 

 

 

'알고리즘' 카테고리의 다른 글

프로그래머스)덧칠하기  (0) 2023.03.05
백준)양  (0) 2023.03.02
백준)정수 삼각형  (0) 2023.02.28
백준)모둔 순열  (0) 2023.02.26
백준)차이를 최대로  (0) 2023.02.26