본문 바로가기

ps(알고리즘)

피보나치 수 6

그냥 n번째 피보나치 수를 구하는 문제인데 값이 커서 최적화를 잘 시켜야 한다.

그냥 이 행렬 곱을 이용해서 구하면 된다.

행렬의 n제곱을 계산하면 되는데 분할정복 느낌?으로 n/2제곱을 계산하는 식으로 재귀함수를 거치면

log(n)의 시간만에 구할 수 있어서 빠르다.

#include<stdio.h>
long long N;
long long K = 1000000007;
long long dp[2][2];
void fibo(long long n){
    if(n==1) return;
    long long m = n/2;
    fibo(m);
    long long mm[2][2];
    mm[0][0] = dp[0][0]*dp[0][0]%K + dp[0][1]*dp[1][0]%K;
    mm[0][1] = dp[0][0]*dp[0][1]%K + dp[0][1]*dp[1][1]%K;
    mm[1][0] = dp[1][0]*dp[0][0]%K + dp[1][1]*dp[1][0]%K;
    mm[1][1] = dp[1][0]*dp[0][1]%K + dp[1][1]*dp[1][1]%K;
    mm[0][0] %= K;
    mm[0][1] %= K;
    mm[1][0] %= K;
    mm[1][1] %= K;

    if(n%2==1){
        dp[0][0] = (mm[0][0] + mm[0][1]) % K;
        dp[0][1] = mm[0][0] % K;
        dp[1][0] = (mm[1][0] + mm[1][1]) % K;
        dp[1][1] = mm[1][0] % K;
    }
    else{
        dp[0][0] = mm[0][0];
        dp[0][1] = mm[0][1];
        dp[1][0] = mm[1][0];
        dp[1][1] = mm[1][1];
    }
    return;
}
int main()
{
    dp[0][0] = 1;
    dp[0][1] = 1;
    dp[1][0] = 1;
    dp[1][1] = 0;
    scanf("%lld",&N);
    fibo(N);
    printf("%lld",dp[0][1]);
}

구현은 그냥 2차원 배열로 행렬 곱을 하나하나 계산해서 했다.

 

'ps(알고리즘)' 카테고리의 다른 글

저울  (0) 2024.09.02
친구 네트워크  (0) 2024.09.02
문제집  (0) 2024.07.17
보석 도둑  (0) 2024.07.13
후위 표기식  (0) 2024.07.13