피보나치 수(Algorithm)
2025. 2. 10. 23:31ㆍC++ study
아이디어!
첫 두항이 0, 1이고
F(n)=F(n-1)+f(n-2), 즉 이전 두 항의 합을 현재 항으로 표기해 주면 된다!
적용
1. 재귀(비효율적)
- 시간 복잡도: O(N^2)
- 중복호출이 많이 발생하기 때문에 비효율적임!
#include <bits/stdc++.h>
using namespace std;
long long fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
cout << fib(n);
}
2. dp활용
- 시간 복잡도: O(N)
- dp배열에 특정 인덱스일 경우의 값을 저장해두고 사용하기!
#include <bits/stdc++.h>
using namespace std;
long long dp[100];
long long fib(int n) {
if (n <= 1) return n;
if (dp[n] != -1) return dp[n];
return dp[n] = fib(n - 1) + fib(n - 2);
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
memset(dp, -1, sizeof(dp));
cout << fib(n);
}
3. 행렬 거듭제곱
- 시간 복잡도: log(N)
- 행렬과 분할정복을 이용한 거듭제곱을 활용하여서 빠르게 해결가능하다.
피보나치 수는 위와 같은 점화식을 따르게 되는 데 이를 행렬 형식으로 나타내면 다음과 같이 나타난다.
행렬을 배운다면 이 식을 쉽게 이해할 수 있기 때문에 행렬을 공부하고 오는 것을 추천한다. 다음은 식을 일반화하게 되면 나오게 되는 결과이다!
이때 N이 1e9,1e10...처럼 커질 수 있기 때문에 분할정복을 활용한 거듭제곱을 활용해 준다면 O(log n)의 시간으로 문제를 해결할 수 있다.
#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
vector<vector<long long>> multiply(vector<vector<long long>> A, vector<vector<long long>> B) { //행렬 계산
vector<vector<long long>> result(2, vector<long long>(2, 0));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
result[i][j] = (result[i][j] + A[i][k] * B[k][j]) % MOD;
}
}
}
return result;
}
vector<vector<long long>> power(vector<vector<long long>> A, long long exp) { //분할정복을 이용한 거듭제곱
vector<vector<long long>> result = {{1, 0}, {0, 1}}; //단위 백터 => 모르면 행렬 공부!
while (exp) {
if (exp % 2) result = multiply(result, A);
A = multiply(A, A);
exp /= 2;
}
return result;
}
int main() {
long long n;
cin >> n;
if (n == 0) {
cout << "0\n";
return 0;
}
vector<vector<long long>> fib_matrix = {{1, 1}, {1, 0}};
vector<vector<long long>> result = power(fib_matrix, n - 1);
cout << result[0][0]; //F(N)출력
}
'C++ study' 카테고리의 다른 글
| 트리 순회 (Tree Traversal) (0) | 2025.02.14 |
|---|---|
| Meet In The Middle (0) | 2025.02.12 |
| 오일러 투어 테크닉 (2) | 2025.02.08 |
| 오일러 함수 (2) | 2025.02.08 |
| 페르마의 소정리 (0) | 2025.02.07 |


