zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    (1)矩阵乘法

    简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C


    其中c[i][j]为A的第i行与B的第j列对应乘积的和,即:

    另外,矩阵也可以用一个结构体来表示

    struct matrix
    {
        ll a[N][N];
    };

    矩阵乘法代码实现:

    matrix mul(matrix x,matrix y)
    {
        matrix temp;
        for(int i = 1 ; i < N ; i++)
            for(int j = 1 ; j < N ; j++)
            temp.a[i][j] = 0;
        for(int i = 1 ; i < N ; i++)
            for(int j = 1 ; j < N ; j++)
                    for(int k = 1 ; k < N ; k++)
                        temp.a[i][j] += x.a[i][k]*y.a[k][j];
        return temp;
    }

    这个实现代码复杂度是O(n^3)的,其实还有更低复杂度的算法实现。利用分块矩阵即可,比较复杂。。不多说了。

    (2)矩阵快速幂

    类似于整数的快速幂,把整数快速幂中的整数换成矩阵、乘法换成矩阵乘法就可以了。

    代码实现:

    matrix quickpow(matrix a,long long n)
    {
        matrix res;
        res.a[1][1] = 1; res.a[1][2] = 0; res.a[1][3] = 0;
        res.a[2][1] = 0; res.a[2][2] = 1; res.a[2][3] = 0;
        res.a[3][1] = 0; res.a[3][2] = 0; res.a[3][3] = 1;//初始化为单位矩阵
        while(n)
        {
            if(n&1) res = mul(res,a);//判断n是否为奇数
            a = mul(a,a);
            n>>=1;//二分
        }
        return res;
    }

    (3)应用

    通过改变转移矩阵的值,将普通递推式改写成矩阵形式。然后用快速幂求解最终矩阵。

    给一道简单例题:poj 3070 http://poj.org/problem?id=3070

    题目:斐波那契数列f(n),给一个n,求f(n)%10000,n<=1e9;(本题是可以用递推完成的,且可以用记忆化数组的方法加速递推,这里略去不做解释)

    解法:先列出Fibonacci递推式: f(1) = 1.f(2) = 2. f(n) = f(n-1) + f(n-2)  (n > 2) 

    接下来建立矩阵形式的递推,找到转移矩阵,记作T*A(n-1) = A(n).(可以推出1*f(n-1)+1*f(n-2)=f(n);1*f(n-1)+0*f(n-2)=f(n-1);)

    得出最终矩阵A(n) = Tn-1*A(1),这里的A(1)成为初始矩阵,接下来利用矩阵快速幂就可以得到res,res[1][1]=f(n)就是我们要求的。

    给一些简单的递推式
    1.f(n)=a*f(n-1)+b*f(n-2)+c;(a,b,c是常数)


    2.f(n)=c^n-f(n-1) ;(c是常数)

  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/zz990728/p/8886836.html
Copyright © 2011-2022 走看看