栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【数学】矩阵加速与斐波那契(fib)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【数学】矩阵加速与斐波那契(fib)

注:本文只适用于C++

一、斐波那契数列的定义:

1. f i b 1 = f i b 2 = 1 , f i b n = f i b n − 1 + f i b n − 2 fib_1 = fib_2 = 1, fib_n = fib_{n - 1} + fib_{n - 2} fib1​=fib2​=1,fibn​=fibn−1​+fibn−2​ 2. f i b n = 5 [ ( 1 + 5 2 ) n − ( 1 + 5 2 ) n ] 5 fib_n = frac {sqrt5 left[left(frac{1 + sqrt 5}{2}right)^n - left(frac{1 + sqrt 5}{2}right)^nright]}{5} fibn​=55 ​[(21+5 ​​)n−(21+5 ​​)n]​

二、求解方法:
1.递归求解,运用递推式递归求解,算法时间复杂度 O ( 2 n ) O(2^n) O(2n)

long long fib(int n) {
    if (n <= 2) return 1;
    else return fib(n - 1) + fib(n - 2);
}

2.线性递推,递推式线性递推,算法时间复杂度 O ( n ) O(n) O(n)

long long fib(int n) {
    int a = 1, b = 1, t;
    for (int i = 3; i <= n; i++) t = a, a = b, b = a + t;
}

3.矩阵加速
经过复杂的递推,我们得到:

所以我们可以用矩阵快速幂与矩阵乘法解出。

#include 
#define ll long long
typedef struct  { ll c[2][2];} m;
using namespace std;
m operator* (m a, m b) {
    m res;
    memset(res.c, 0, sizeof(res.c));
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int z = 0; z < 2; z++)
                res.c[i][j] += a.c[i][z] * b.c[z][j];
    return res;
}
m pows(m a, ll n) {
    m I;
    I.c[0][0] = I.c[1][1] = 1, I.c[0][1] = I.c[1][0] = 1;
    while (n > 1) {
        if (n & 1) I = I * a;
        n >>= 1, a = a * a;
    }
    return I * a;
}
long long fib(int n) {
    m A, H;
    if (n <= 2) return 1;
    A.c[0][0] = 1, A.c[0][1] = 1, A.c[1][0] = 1, A.c[1][1] = 0;
    A = pows(A ,n - 2);
    H.c[0][0] = 1, H.c[0][1] = 0, H.c[1][0] = 1, H.c[1][1] = 0;
    A = A * H;
    return A.c[0][0];
}

有些题目数码很大需要取模,所以矩阵快速幂亦可取模,假设模10000,则代码变为

#include 
#define ll long long
typedef struct  { ll c[2][2];} m;
using namespace std;
const int mod = 10000 //此处为10000
m operator* (m a, m b) {
    m res;
    memset(res.c, 0, sizeof(res.c));
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int z = 0; z < 2; z++) {
                res.c[i][j] += a.c[i][z] * b.c[z][j];
                res.c[i][j] %= mod
            }
    return res;
}
m pows(m a, ll n) {
    m I;
    I.c[0][0] = I.c[1][1] = 1, I.c[0][1] = I.c[1][0] = 1;
    while (n > 1) {
        if (n & 1) I = I * a;
        n >>= 1, a = a * a;
    }
    return I * a;
}
long long fib(int n) {
    m A, H;
    if (n <= 2) return 1;
    A.c[0][0] = 1, A.c[0][1] = 1, A.c[1][0] = 1, A.c[1][1] = 0;
    A = pows(A ,n - 2);
    H.c[0][0] = 1, H.c[0][1] = 0, H.c[1][0] = 1, H.c[1][1] = 0;
    A = A * H;
    return A.c[0][0];
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/998054.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号