码迷,mamicode.com
首页 > 其他好文 > 详细

斐波那契

时间:2015-01-21 19:55:05      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

斐波那契

斐波那契

迭代的斐波那契

斐波那契有很多种写法,不会递归的同学就会这样写:

int fib0(int n) {
    int a = 1;
    int b = 1;
    int c;

    if(n == 1 || n == 2) {
        return 1;
    }
    for (int i = 2; i < n; i++) {
        c = a + b;
        b = a;
        a = c;
    }
    return c;
}
#define MAXN 1000
int fib_dp(int n) {
    int f[MAXN];

    f[1] = 1;
    f[2] = 1;
    if (n == 1 || n == 2) {
        return 1;
    }
    for (int i = 2; i <= n; i++) {
        f[i] = f[i-1] + f[i-2];
    }
    return f[n];
}

递归写法的斐波那契

递归的写法:

int fib1(int n) {
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        return fib1(n-1) + fib1(n-2);
    }
}

带记忆的递归写法:

#define MAXN  1000
int a[MAXN];

void fib2_init(void) {
    memset(a, -1, sizeof(a));
    a[0] = 1;
    a[1] = 1;
}
int fib2(int n) {
    if (a[n] > 0) {
        return a[n];
    } else {
        a[n] = fib2(n-1) + fib2(n-2);
        return a[n];
    }
}

// 调用的时候就必要先初始化下
int main() {
    fib2_init();
    fib2(n);
}

采用矩阵快速求斐波那契

然而,上面的各种写法都不是最快的写法。由矩阵的知识可以推出:

[An  ]   [ An       ]   [0 1] . . [An-1]
       =              =        .
[An+1]   [ An-1 + An]   [1 1] . . [An  ]
       [0 1]        N  .  . [0]     [An  ]
令 A =        , 则  A    .       ==>
       [1 1]           .  . [1]     [An+1]

当然要写出上面的程序还需要会 求矩阵乘法,求阶乘。

矩阵乘法:

struct matrix {
    int m[2][2];
};

matrix matrix_multi(matrix a, matrix b) {
    matrix c;
    memset(&c, 0, sizeof(matrix));     // 将数据初始化为0
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                c.m[i][j] = c.m[i][j] + a.m[i][k] * b.m[k][j];
            }
        }
    }

    return c;
}

求阶乘

在int整数类型的时候,我们可以这样求阶乘:

int pow(int a, int n) {
    if (n == 1) {
        return a;
    } else if (n % 2 == 0) {
        int b = pow(a, n / 2);
        return b * b;
    } else if (n % 2 == 1) {
        return a * pow(a, n-1);
    }
}

现在换成是矩阵:

matrix matrix_pow(matrix a, int n) {
    if (n == 1) {
        return a;
    } else if (n % 2 == 0) {
        matrix b = matrix_pow(a, n / 2);
        return matrix_multi(b, b);
    } else if (n % 2 == 1) {
        return matrix_multi(a, matrix_pow(a, n-1));
    }
}

最后我们还需要一个包装函数:

int fib_matrix(int n) {
    if (n == 0) {
        return 0;
    }
    matrix init;
    init.m[0][0] = 0;
    init.m[0][1] = 1;
    init.m[1][0] = 1;
    init.m[1][1] = 1;

    matrix t = matrix_pow(init, n);
    int res = t.m[0][1];

    return res;
}

斐波那契

标签:

原文地址:http://www.cnblogs.com/sunznx/p/4239824.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!