BOJ_1463 1로 만들기 -Python3
문제분석
1. 관찰
- 입력: 1000000 => 백만
- N%3 == 0 => nxt = N / 3
- N%2 == 0 => nxt = N / 2
- nxt = N - 1
- 출력: N을 1로 만드는 연산의 최소 횟수
- 3 으로 나누기, 2로 나누기, 1빼기 순으로 진행할 수로 연산을 줄일 수 있다.
구하려는 값은 N을 1로 만드는 연산의 최소 횟수이다.
N이 1이 될때연산의 횟수는 이전의 연산에 영향을 받는다.
=> dp 1~N까지 기억하여 연산, cnt는 1,2,3이 되는데 필요한 연산 횟수를 초기화 하고 N이 될때 필요한 연산을 1에서 부터 N이 될때 까지 보텀엄 방식으로 연산한다.
dp : 0 1 2 3 4 5 6 7 ...
cnt : 0 0 1 1 ... 점화식
보텀업 방식으로 연산
2. 복잡도
- O(N) = 10**6 >> 10만 가능
3. 자료구조
- dp : int[]
해결코드
import sys
si = sys.stdin.readline
N = int(si())
dp = [0 for _ in range(N+1)]
for n in range(2,N+1): # 2부터 N이 될때 까지 필요한 연산횟수 리턴
# 1을 더하는 방식 2,3을 곱하는 방식 연산 횟수 비교하여 초기화
if n%3==0 and n%2==0:
dp[n] = min(dp[n-1], dp[n//2], dp[n//3])+1
elif n%3==0 and n%2!=0:
dp[n] = min(dp[n-1], dp[n//3])+1
elif n%3!=0 and n%2==0:
dp[n] = min(dp[n-1], dp[n//2])+1
else:
dp[n] = dp[n-1] + 1 # dp[2], dp[3] 각각 연산횟수 1,1로 초기화됨
print(dp[N])
배운점
다이나믹 프로그래밍은
1. 큰 문제를 작은 문제로 나눌 수 있다.
2. 작은 문제에서 구한 정답은 그것을 포함하는 문제에서도 동일하다.
는 규칙을 만족하는데
이 문제를 계속 고민하다보니
1을 만들기 위한 최소연산 횟수는 이전의 연산 횟수를 구하는 것의 반복임을 발견하게 되었다.
맨 처음에는 dp 배열을 연산에서 어떻게 활용하여야 하나 고민되었는데,
문제에서 구하려는 값이 N을 1로 만드는데 필요한 최소연산 횟수 임으로
N+1길이의 dp 배열에서 연산횟수를 기록하여 연산을 할 수 있다는 것을 이해하였다.
'Etc > PS' 카테고리의 다른 글
[Kakao] 순위 검색 Python3 (0) | 2022.09.29 |
---|---|
BOJ_2217 로프 -Python3 (0) | 2022.08.14 |
BOJ_2164 카드2 -Python3 (0) | 2022.08.12 |
BOJ_2864 5와 6의 차이 -Python3 (0) | 2022.08.11 |
BOJ_5585 거스름돈 -Python3 (0) | 2022.08.11 |