반응형
문제
다음 소스는 N번째 피보나치 수를 구하는 C++ 함수이다.
int fibonacci(int n) {
if (n == 0) {
printf("0");
return 0;
} else if (n == 1) {
printf("1");
return 1;
} else {
return fibonacci(n‐1) + fibonacci(n‐2);
}
}
fibonacci(3)을 호출하면 다음과 같은 일이 일어난다.
- fibonacci(3)은 fibonacci(2)와 fibonacci(1) (첫 번째 호출)을 호출한다.
- fibonacci(2)는 fibonacci(1) (두 번째 호출)과 fibonacci(0)을 호출한다.
- 두 번째 호출한 fibonacci(1)은 1을 출력하고 1을 리턴한다.
- fibonacci(0)은 0을 출력하고, 0을 리턴한다.
- fibonacci(2)는 fibonacci(1)과 fibonacci(0)의 결과를 얻고, 1을 리턴한다.
- 첫 번째 호출한 fibonacci(1)은 1을 출력하고, 1을 리턴한다.
- fibonacci(3)은 fibonacci(2)와 fibonacci(1)의 결과를 얻고, 2를 리턴한다.
1은 2번 출력되고, 0은 1번 출력된다. N이 주어졌을 때, fibonacci(N)을 호출했을 때, 0과 1이 각각 몇 번 출력되는지 구하는 프로그램을 작성하시오.
문제풀이
dp=[None]*41
dp[0]=[1,0]
dp[1]=[0,1]
t=int(input())
for i in range(t):
a = int(input())
if a==0 or a==1:
print(*dp[a])
else:
for j in range(2,a+1):
dp[j]=[dp[j-1][1],dp[j-1][0]+dp[j-1][1]]
print(*dp[a])
'''
0 : 1 0
1 : 0 1
2 : 1 1
3 : 1 2
4 : 2 3
5 : 3 5
6 : 5 8
7 : 8 13
8 : 13 21
9: 21 34
'''
- 문제의 핵심은 다이나믹 프로그래밍 즉 점화식을 찾는 것이다.
- 해당 문제의 규칙을 찾아보면 2부터 dp[j]=[dp[j-1][1],dp[j-1][0]+dp[j-1][1]]라는
규칙이 반복되는 것을 확인할 수 있다.
- 그렇기에 0과 1의 값만 추가해주고, 2부터는 for문을 돌려가며 a값에 해당하는 값을 찾으면 된다.
+ 참고로 for문을 통해 dp[a]값이 이미 그전에 구한 상태라면 바로 출력될 수 있게
조건문을 넣을 수도 있다. 하지만 이번 문제에서는 시간이 충분하기에
따로 넣지는 않았다.
'프로그래밍 > 백준' 카테고리의 다른 글
[알고리즘] 백준 25757 파이썬 - 임스와 함께하는 미니게임 (0) | 2022.11.22 |
---|---|
[알고리즘] 백준 17087 파이썬 - 숨바꼭질6 (유클리드 호제법) (0) | 2022.11.21 |
[알고리즘] 백준 15654 파이썬 - N과 M(5) (백트래킹) (1) | 2022.11.19 |
[알고리즘] 백준 17103 파이썬 - 골드바흐 파티션(에라토스테네스의 체) (0) | 2022.11.18 |
[알고리즘] 백준 10974 파이썬 - 모든 순열 (0) | 2022.11.17 |