문제
영선이는 매우 기쁘기 때문에, 효빈이에게 스마일 이모티콘을 S개 보내려고 한다.
영선이는 이미 화면에 이모티콘 1개를 입력했다. 이제, 다음과 같은 3가지 연산만 사용해서 이모티콘을 S개 만들어 보려고 한다.
- 화면에 있는 이모티콘을 모두 복사해서 클립보드에 저장한다.
- 클립보드에 있는 모든 이모티콘을 화면에 붙여넣기 한다.
- 화면에 있는 이모티콘 중 하나를 삭제한다.
모든 연산은 1초가 걸린다. 또, 클립보드에 이모티콘을 복사하면 이전에 클립보드에 있던 내용은 덮어쓰기가 된다. 클립보드가 비어있는 상태에는 붙여넣기를 할 수 없으며, 일부만 클립보드에 복사할 수는 없다. 또한, 클립보드에 있는 이모티콘 중 일부를 삭제할 수 없다. 화면에 이모티콘을 붙여넣기 하면, 클립보드에 있는 이모티콘의 개수가 화면에 추가된다.
영선이가 S개의 이모티콘을 화면에 만드는데 걸리는 시간의 최솟값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 S (2 ≤ S ≤ 1000) 가 주어진다.
출력
첫째 줄에 이모티콘을 S개 만들기 위해 필요한 시간의 최솟값을 출력한다.
예제 입력 12
|
예제 출력 12
|
예제 입력 24
|
예제 출력 24
|
예제 입력 36
|
예제 출력 35
|
예제 입력 418
|
예제 출력 48
|
풀이
간단하게 풀릴 것 같았는데, 생각보다 까다로웠던 문제이다.
BFS에 DP를 적용하여 풀이해야 한다.
처음엔 단순히 이모티콘의 개수별로 최단 시간을 담는 visit dp배열을 만들었었다.
하지만 38% 부근에서 계속하여 틀렸습니다를 마주했다.
이유는 다음과 같다.
현재 개수가 x일때 3 - 2 연산이 최단 시간으로 S개의 이모티콘을 만든다고 하자.
하지만 만약 dp[x-1]에 현재 소요 시간보다 같거나 적은 수가 있을 경우 큐에 담지 못해 해당 연산을 수행할 수 없는 것이다.
따라서 2차원 배열로 문제를 해결한다.
dp배열은 dp[클립보드][현재이모티콘의수]로 사용한다.
from collections import deque
import sys
input = sys.stdin.readline
n = int(input())
dp = [[float('inf')] * (n+2) for _ in range(1001)]
q = deque([(1,0,0)])
while q:
num,t,clip = q.popleft()
if num == n: # 정답 도출
print(t)
break
t+=1
for dnum in num+clip,num-1: # 복붙, -1
if n+2>dnum>0 and dp[clip][dnum] > t:
dp[clip][dnum] = t
q.append((dnum,t,clip))
q.append((num,t,num)) # 복사
'알고리즘 연습 > DFS와 BFS' 카테고리의 다른 글
[🥇5 / 백준 13023 / 파이썬] ABCDE (0) | 2022.01.23 |
---|---|
[🥇5 / 백준 16234 / 파이썬] 인구 이동 (0) | 2022.01.14 |
[🥈2 / 백준 11060 / 파이썬] 점프 점프 (0) | 2021.12.28 |
[🥇4 / 백준 5427 / 파이썬] 불 (0) | 2021.12.08 |
[🥈1 / 백준 1325 / 파이썬] 효율적인 해킹 (0) | 2021.12.04 |