solved_ac[Class3][피보나치 함수](https://www.acmicpc.net/problem/1003)
다음 소스는 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)을 호출하면 다음과 같은 일이 일어난다.
1은 2번 출력되고, 0은 1번 출력된다. N이 주어졌을 때, fibonacci(N)을 호출했을 때, 0과 1이 각각 몇 번 출력되는지 구하는 프로그램을 작성하시오.
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. N은 40보다 작거나 같은 자연수 또는 0이다.
각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.
3
0
1
3
1 0
0 1
1 2
2
6
22
5 8
10946 17711
[백준]11050번: 이항 계수 1의 업그레이드 문제이다. dp를 이용해서 푸는 것인데, 이미 계산된 결과는 별도의 메모리 영역에 저장하여 다시 계산하지 않도록 하게끔 해서 수행 시간 효율성을 향상시킬수 있다.
11050번에 dp에 대해 자세한 설명이 있으니 참고하도록 하자.
0 -> (1, 0)
1 -> (0, 1)
2 -> (1, 1)
3 -> (1, 2)
4 -> (2, 3)
5 -> (3, 5)
6 -> (5, 8)
숫자가 하나 증가할 때마다 1이 나오는 횟수가 1 증가한 숫자의 0이 나오는 횟수와 같아지며 1 증가한 숫자의 1이 나오는 횟수는 그 전 0이 나오는 횟수와 1이 나오는 횟수의 합과 같다.
무슨 얘기냐면 숫자 6의 값을 봐보자. 6은 5와 8을 출력하게 되는데 이는 5에서 (3, 5)에서 5가 6의 첫번째 숫자로 가고 3과 5의 합인 8은 숫자 6의 두번째 값인 8이 된다.
점화식 : list[i] = [list[i - 1][1], list[i - 1][0] + list[i - 1][1]]
import sys
T = int(sys.stdin.readline())
fibo_zero = [1, 0]
fibo_one = [0, 1]
for i in range(T):
a = int(sys.stdin.readline())
if a == 0:
print("1 0")
continue
elif a == 1:
print("0 1")
continue
else:
for i in range(len(fibo_zero), a + 1):
fibo_zero.append(fibo_one[i - 1])
fibo_one.append(fibo_zero[i - 1] + fibo_one[i - 1])
print(fibo_zero[a], fibo_one[a])
점화식 : list[i] = [list[i - 1][1], list[i - 1][0] + list[i - 1][1]]
import sys
T = int(sys.stdin.readline())
d = [[0, 0] for _ in range(41)]
d[0][0] = 1
d[0][1] = 0
d[1][0] = 0
d[1][1] = 1
def dp(x):
if x == 0 or x == 1 or d[x][0] != 0:
return d[x]
else:
a = dp(x - 1)
d[x][0] = a[1]
d[x][1] = a[0] + a[1]
return d[x]
for i in range(T):
a = int(sys.stdin.readline())
dp(a)
print(d[a][0], d[a][1])
dp 테이블을 [[0, 0] for _ in range(41)]로 초기화 하는 것이 아닌 [0] * 41로 초기화를 해주고 2차원 배열로 사용하였다. 그랬더니 TypeError가 떴다. 답을 출력하는데는 문제가 없지만 1차원으로 초기화를 하고 2차원으로 사용을 하니 타입에러가 뜬것 같아서 다시 2차원으로 초기화를 해주었다. 첫번째로 푼 풀이도 어떻게 보면 dp를 사용한게 아닌가 싶다. 이미 연산을 끝낸 테이블은 값을 이용하여 같은 연산을 하지 않고 진행을 했다는 점에서 dp와 유사하지만 두 코드의 다른점은 첫번째 코드는 바텀업 방식을 이용하였고 두번째 코드는 탑다운 방식을 이용하여 풀었다는 것이다.