지금 피곤해서 그런지 솔직히 DP 개념이 잘 머리에 안 들어온다.
그래서 DP문제치고 굉장히 쉬운 편에 속하는 해당 개념도 인식이 잘 안 됐다.
30분 책상에 엎드려서 자고 왔다.
import sys
input = sys.stdin.readline
x = int(input())
dp = [0]*(x+1)
for i in range(2,x+1):
dp[i] = dp[i-1] + 1
if i % 3 == 0:
dp[i] = min(dp[i],dp[i//3] + 1)
if i % 2 == 0:
dp[i] = min(dp[i],dp[i//2] + 1)
print(dp[x])
다른 분의 코드를 보니 코드 자체는 이해 가는데, 이걸 내가 습득한 개념처럼 안 다가온다.
조금 쉬고 다시 보자.
1. 테이블 정의하기
: 어이없게도 리스트 초기화에서 에러가 났다. 아까 피곤해서 자꾸 빈 배열로 초기화를 한 뒤 값을 append가 아닌 = 로 할당하려 해서였다.
테이블은 0을 값으로 가지는 수를 하나 많게 곱해서 초기화
2. 재귀식 찾기
: 모든 문제가 그렇겠지만 재귀식을 찾는게 까다로운 문제다. 자칫 잘못하면 n 부터 시작해 값을 빼거나 나눠가며 1까지 단순하게 구할 수 있는데, 친절하게 제시된 두 번째 테스트 케이스에서 그렇게 하면 안 된다는 것을 알 수 있다.
: 그래서 초기값을 채워넣은 뒤 나머지를 반복 돌며 채워나간다. 라는 DP의 특성을 다시 잘 생각해본 뒤 풀이하면 조금 더 괜찮다.
: 특히 DP:Dynamic Programming:동적계획법은 하향식과 상향식이 있다. 는 3년 전 배운 사실을 다시 상기시키며 계속 문제를 더 많이 접하면 사실 어렵지 않다.
: 그래서 해당 문제도 처음 접근했던 상향식이 아닌 하향식으로 풀면 해결이 가능했다.
: 혼자 풀어야한다고 다시 접근해보자 . 상향식인지 하향식인지 키워드는 어디서 얻을 수 있을까.
:목표값 x에서 최소 연산횟수를 가지며 1) 3으로 나누거나 2) 2로 나누거나 3) 1을 빼야한다. 해당플로우를 bfs로 모두 탐색하지 않는 이상 3가지 경우 중 어떤 것이 최소 연산을 가질 지 미래의 일은 DP를 통해 구하기는 까다롭다.
반대로 1,2 의 케이스부터 생각해서 다음 수가 3가지 방법 중 어떤 것들이 결합했을 때 연산횟수가 적을 지는 비교하기 쉽다.
그리고 이 때 테이블에 넣을 값이 더 면밀하고 확실하게 정해지는데, 우리가 구하고자 하는 값인 연산횟수를 바로 업데이트하며 올라오면 되는 것이다.
3. 초기값 정하기
: 물론 1일때, 값이 1이라고 제시되었으니 초기값은 1
위와 같은 사고방식이 다른 DP문제에서도 통할 지 계속 풀어보자.
'CodingTest > Baekjun Online Judge' 카테고리의 다른 글
[ BOJ / 파이썬 ] 1149 RGB거리 (0) | 2022.08.03 |
---|---|
[ BOJ / 파이썬] 2579 계단 오르기 (0) | 2022.08.03 |
[ BOJ / 파이썬 ] 11652 카드 (0) | 2022.07.29 |
[ BOJ / 파이썬 ] 1431 시리얼 번호 (0) | 2022.07.29 |
[ BOJ / 파이썬 ] 15688 수 정렬하기 5 (0) | 2022.07.29 |