-
[Python] BOJ 2748 : 피보나치 수 2코딩테스트/백준 2024. 9. 27. 20:15
요구사항
- 시간 제한 1초
- N이 90이하 이므로 O(N^3) 까지 가능할 것.
- 메모리 제한 128MB
- N이 매우 작으니 신경 안 써도 될 것.
- N이 주어질 때, N번 째 피보나치 수를 출력한다.
- ex) N = 3이면, 0,1,1 -< 1을 출력.
설계
위 문제는 주관적인 생각으론 3가지 방법으로 풀어보고 싶다.
- 재귀함수
- 사용자 정의 함수 안의 base case 설정 : N = 1일때 0을 N = 2일 때 1을 출력할 수 있게 한다.
- 그 외 return 함수(N-1) + 함수(N-2) 를 할 수 있도록 한다.
- Top-Down
- 위 방식은 큰 문제를 작은 단위의 문제로 나누어 쪼개는 동적계획법 알고리즘 설계 방법 중 하나이다.
- 동적 계획법 즉, DP는 메모제이션을 사용한다. 메모제이션이란,,, 냉장고라고 생각하면 된다. 마트까지 가지 않고 원하는 값을 냉장고에서 꺼내 먹는... 비유는 잊으세요...
- 저장할 리스트를 N개만큼 초기화 해준다.
- 사용자 정의 함수를 돌린 결과값을 초기화 해준 리스트에 저장해준다.
- 그 외는 재귀 함수의 설계와 비슷합니다. 아래 구현에서 봬요.
- Bottom-Up
- 위 방식은 큰 문제를 풀긴 하는 데 작은 문제부터 해결해 큰 문제를 해결하는 방식 이라고 생각하면 편하다.
- 결과값을 저장할 리스트를 초기화해준다.
- base case 를 설정해준다.
- for문을 이용해 해결한다.
구현
- 재귀함수
def fibo(N): if N == 1: return 0 elif N == 2: return 1 else: return fibo(N-1) + fibo(N-2) print(fibo(int(input()))
실수?
- 0번 째 피보나치 수는 0이다. ㅋㅋㅋ 1 번 째가 아니라 ㅠㅠ
- 따라서 아래와 같이 수정해줘야 한다.
def fibo(N): if N == 0: return 0 elif N == 1: return 1 else: return fibo(N-1) + fibo(N-2) print(fibo(int(input())))
- 백준에서 위 소스 코드는 시간 초과가 난다.
- 그 이유는 아래와 같다.
fibo(5) └── fibo(4) └── fibo(3) └── fibo(2) └── fibo(1) └── fibo(2) └── fibo(3) └── fibo(2) └── fibo(1)
- 피보나치 수열의 계산의 시간 복잡도가 O(2^N) 이므로 초반 요구사항인 O(N^3)을 만족하지 못하기 때문이다.
- 따라서 방식 2, 3번으로 문제를 제출하면 되겠다.
2. Top-Down
def fibo(N): if N == 0: return 0 elif N == 1: return 1 if dp[N] != 0: return dp[N] dp[N] = fibo(N-1) + fibo(N-2) return dp[N] N = int(input()) dp = [0] * (N+1) print(fibo(N))
- 1번 재귀 함수로 풀 경우 같은 값을 반복해서 계산한다. 예를 들어 fibo(5)를 계산할 때, fibo(4)와 fibo(3) 을 계산한다. 근데 fibo(4)를 계산하려면 fibo(3)과 fibo(2)를 다시 계산한다. 즉, 같은 피보나치 값을 여러 번 중복으로 계산하게 된다.
- 하지만 top-down 방식으로 피보나치 수열을 계산 하면, 메모리에 값을 저장해 중복을 막아준다.
- 그래서 시간 복잡도 O(N)을 갖는다.
3. Down-Up
N = int(input()) dp = [0] * (N+1) dp[0] = 0 dp[1] = 1 for i in range(2, N+1): dp[i] = dp[i-1] + dp[i-2] print(dp[N])
- 여기서 for문이 2부터 시작하는 건, dp의 0과 1에 대한 basecase를 설정해주었기 때문이다.
'코딩테스트 > 백준' 카테고리의 다른 글
[Python] BOJ 9084 : 동전 (0) 2024.09.29 [Python] BOJ 1904 : 01타일 (0) 2024.09.28 [Python] BOJ 11725 : 트리의 부모 찾기 (1) 2024.09.25 [Python] BOJ 2606 : 바이러스 (0) 2024.09.25 [Python] BOJ 11724 : 연결 요소의 개수 (0) 2024.09.25 - 시간 제한 1초