밥풀의 개발일지
백준 1003번 - 파이썬 본문
안녕하세요 밥풀입니다.!
오늘 풀어볼 백준 문제는 1003번입니다.
https://www.acmicpc.net/problem/1003
1003번: 피보나치 함수
각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.
www.acmicpc.net
접근방법
이 문제는 얼핏보면 굉장히 쉬운 문제처럼 보이지만 시간제한이 0.25초라는것을 볼 수 있고 조금은 아이디어가 필요한 문제라는 것을 알 수 있습니다. 문제에 나와있는 c++함수의 경우에는 O(2^n)이라는 무시무시한 시간복잡도를 가지고 있기 때문에 쓸 수 없습니다! 대신 메모이제이션을 사용하면 더 빠른 성능 좋은 피보나치 수열 코드를 만들 수 있습니다.
메모이제이션을 쉽게 말하자면 이미 계산한 값은 메모해둔 곳에서 가져와서 계산을 함으로써 불필요한 시간을 단축시키는 것입니다!
저는 이 문제를 풀면서 굉장히 어렵게 접근을 했는데 아마 피보나치 수열의 특성을 잘 알고 계신 분들이라면 어렵지 않게 풀 수 있지 않을까 싶습니다.
피보나치 수열은
F(1) = 1
F(2) = 1
F(N) = F(N-1) + F(N-2) (N >2)
라는 조건을 가지고 있는데요
0의 개수를 Z(n) 1의 갯수를 O(n)이라고 가정하고
n이 n-1 과 n-2로 재귀 호출을 하니까 Z(n) = Z(n-1) + Z(n-2)와 O(n) = O(n-1) + O(n-2)가 성립합니다.
그래서 우리는 Z(n)과 O(n)의 점화식이 동일한 것을 확인할 수 있슴니다!
하지만 시작값이 조금 다른 것을 확인할 수 있는데
Z(n)의 경우 n = 0부터 1, 0, 1, 1 ...이고 O(n)의 경우 0, 1, 1, 2 ... 인것을 확인할 수 있는데
Z(n)의 수열은 O(n)의 수열과 비교하면 앞에 1을 하나더 추가하면 동일한 것을 확인할 수 있습니다!
그렇기 때문에 우리는 Z(n+1) = O(n) 이 성립하는 것을 확인할 수 있습니다.
그러면 설명은 끝났습니다.
출력을 할 때 "Z(n+1) O(n)"만 출력을 하면 정답이 나온다는 것을 유추할 수 있습니다.
그리고 시간 복잡도 또한 O(2n)인데 상수는 때버리고 계산하면 O(N)인 것을 알 수 있습니다.
def fibonacci(n, memo = {}):
if n in memo:
return memo[n]
if n == 0:
return 0
elif n == 1:
return 1
else:
memo[n] = fibonacci(n-1, memo) + fibonacci(n-2, memo)
return memo[n]
T = int(input())
for _ in range(T):
number = int(input())
if number == 0:
print(1, 0)
elif number == 1:
print(0, 1)
else:
print(fibonacci(number-1), fibonacci(number))
'공부' 카테고리의 다른 글
| [기술 리뷰] MCP 간단 사용기(클로드-파일시스템 일부 연결) (1) | 2025.05.07 |
|---|---|
| [기술 리뷰] BitNet 간단 사용기(설치부터 사용까지) (0) | 2025.05.05 |
| [자료구조] 배열을 이용하여 Stack 구현하기(c 언어) (0) | 2023.11.08 |
| LAN(근거리 통신망)이란? (0) | 2023.11.08 |
| 컴파일 언어와 인터프리터 언어의 특징과 종류 (0) | 2023.09.10 |