Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 학습장
- 영수증 ocr
- 일기장
- 스케치데이터셋
- 1149번
- object detection
- 9095번
- 네부캠
- 다국어 ocr
- zero-shot classification
- 머신러닝 사이클
- imageclassification
- 11727번
- 객체탐지
- 타일링2
- 회귀모델
- 재활용 품목분류
- Diffusion
- 네이버부스트캠프
- 네이버 부스트캠프
- pytorch
- Aimers
- 부스트캠프
- 쓰레기분류
- 네이버부스트 캠프
- 스케치이미지
- dp
- 이미지분류
- 백준
- 모델평가지표
Archives
- Today
- Total
john8538 님의 블로그
백준-9095번 1,2,3 더하기 본문
https://www.acmicpc.net/problem/9095
DP란?
Divide-And-Conquer : Top-down approach
- 나누어진 부분들 사이에 서로 상관관계가 없는 문제를 해결하는데 적합
- 피보나치 알고리즘의 경우에는 나눈어진 부분들이 서로 연관이 있다.
- 즉, 분할정복식 방법을 적용하여 알고리즘을 설계하게 되면 같은 항을 한 번 이상 계산하는 결과를 초래하게 되므로 효율적이지 않다. 따라서 이 경우에는 분할정복식 방법은 적합하지 않다.
Dynamic programming: bottom-up approach
- 큰 문제를 작은 문제로 나눈 다는 점은 Divde-And-Conquer와 동일하다.
- 그러나 작은 문제를 먼저 해결하고, 그 결과를 저장한 다음, 후에 그 결과가 필요할 때마다 다시 계산하는 것이 아니고 저장된 결과를 이용해 도출해낸다.
- 여기에서의 Programming → 해답을 구축하는데 배열(테이블)을 사용함을 의미한다.
전에 결과를 이용해서 원하는 결과를 도출해낸다는 DP의 정의에 따라 접근해보자.
먼저 1을 1,2,3의 합으로 나타내는 방법은 1 = 1 한 가지다.
다음 2를 1,2,3의 합으로 나타내면 2 = 1+2 , 2 두 가지이다.
반복해가며 규칙을 발견해보자.
1 | 1 | 1개 |
2 | 1+1 2 |
2개 |
3 | 1+1+1 1+2 (2개) 3 |
4개 |
4 | 1+1+1+1 1+1+2 (3개) 2+2 1+3 (2개) |
7개 |
5 | 1+1+1+1+1 1+1+1+2 (4개) 1+2+2 (3개) 1+1+3 (3개) 3+2 (2개) |
13개 |
6 | 1+1+1+1+1+1 1+1+1+1+2 (5개) 1+1+2+2 (6개) 1+1+1+3 (4개) 2+2+2 2+3+1 (6개) 3+3 |
24개 |
7 | - | 44개 |
살펴보게 되면 전에 구했던 숫자들이 다음 숫자를 구성하는데 포함됨을 확인할 수 있다.
우선 1,2,3 인 경우는 기본으로 크게 규칙이 없이 기본으로 제공이 된다.
즉 A(1) = 1, A(2) = 2, A(3) = 4 이다.
A(4)인 경우를 살펴보게 되면, 이 경우에는 A(1) + 3, A(2) + 2, A(3) + 1로 이루어진다.
각 값을 만들어주기 위한 값에 추가로 숫자를 더해주면 되는 것이다.
점화식을 작성해보게 되면 A(n) = A(n-1) + A(n-2) + A(n-3) 이다.
이 결과를 바탕으로 코드를 작성해보자.
나는 처음엔 재귀로 작성하였다.
def dp(n):
if(n == 1):
return 1
elif(n == 2):
return 2
elif(n == 3):
return 4
else:
return(dp(n-1)+dp(n-2)+dp(n-3))
T=int(input())
for i in range(T):
n = int(input())
print(dp(n))
하지만 이렇게 작성하게 되면 계산량이 늘어나 시간초과가 발생할 수 있다.
다행? 이도 이번문제에서는 통과를 했으나 반복문이나, 리스트에 저장해가며 작성하는걸 추천한다.
이를 개선한 버전은 아래와 같다.
def dp(n):
if n <= 3:
return [0, 1, 2, 4][n]
# n+1 크기의 리스트를 생성하고 초기값을 설정
dp_list = [0] * (n + 1)
dp_list[1] = 1
dp_list[2] = 2
dp_list[3] = 4
# 4부터 n까지 값을 계산하여 리스트에 저장
for i in range(4, n + 1):
dp_list[i] = dp_list[i-1] + dp_list[i-2] + dp_list[i-3]
return dp_list[n]
T = int(input())
for _ in range(T):
n = int(input())
print(dp(n))
'백준 & 알고리즘' 카테고리의 다른 글
백준-1149번 RGB거리 (0) | 2024.08.16 |
---|---|
백준-11727번 2xn 타일링 2 (0) | 2024.08.16 |