zoukankan      html  css  js  c++  java
  • 矩阵二分快速幂优化dp动态规划



    矩阵快速幂代码:

    int n; // 所有矩阵都是 n * n 的矩阵
    struct matrix {
       int a[100][100];
    };
    matrix matrix_mul(matrix A, matrix B, int mod) {
        // 2 个矩阵相乘
        matrix C;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                C.a[i][j] = 0;
                for (int k = 0; k < n; ++k) {
                    C.a[i][j] += A.a[i][k] * B.a[k][j] % mod;
                    C.a[i][j] %= mod;
                }
            }
        }
        return C;
    }
    matrix unit() {
        // 返回一个单位矩阵
        matrix res;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (i == j) {
                    res.a[i][j] = 1;
                } else {
                    res.a[i][j] = 0;
                }
            }
        }
        return res;
    }
    matrix matrix_pow(matrix A, int n, int mod) {
        // 快速求矩阵 A 的 n 次方
        matrix res = unit(), temp = A;
        for (; n; n /= 2) {
            if (n & 1) {
                res = matrix_mul(res, temp, mod);
            }
            temp = matrix_mul(temp, temp, mod);
        }
        return res;
    }
    

    矩阵快速幂模板

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn = 110;
    const int MOD = 1e9 + 7;
    #define mod(x) ((x)%MOD)
    
    //https://www.51nod.com/Challenge/Problem.html#!#problemId=1113
    
    int n;
    
    struct mat{
    	int m[maxn][maxn];
    }unit;
    
    //重载矩阵的乘法 
    mat operator * (mat a,mat b){
    	mat ret;
    	ll x;
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			x = 0;
    			for(int k=0;k<n;k++){
    				x += mod((ll)a.m[i][k] * b.m[k][j]);
    			}
    			ret.m[i][j] = mod(x);
    		}
    	}
    	return ret;
    }
    
    //初始化矩阵 
    void init_unit(){
    	for(int i=0;i<maxn;i++)
    		unit.m[i][i] = 1;
    	return;
    }
    
    //矩阵快速幂 前面代码已经重载过乘法运算 并取模 :就等于二分快速幂 + 矩阵乘法 
    mat pow_mat(mat a,ll n){
    	mat ret = unit;
    	while(n){
    		if(n&1) ret = ret*a;
    		a = a*a;
    		n >>= 1;
    	}
    	return ret;
    }
    
    
    
    int main(){
    	ll x;
    	init_unit();
    	cin>>n>>x; 
    	mat a;
    	
    	//输入数据 
    	for(int i = 0;i < n;i++){
    		for(int j=0;j<n;j++){
    			cin>>a.m[i][j];
    		}
    	}
    	
    	a = pow_mat(a,x);//计算a矩阵的x次幂 
    	
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			if(j+1==n) cout<<a.m[i][j]<<endl;
    			else cout<<a.m[i][j]<<" ";
    		}
    	}
    	
    	return 0;
    } 
    
  • 相关阅读:
    数据结结构学习 赫夫曼树
    C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法
    Linux/Unix time时间戳的处理转换函数
    gcc中include文件的搜索路径
    数据结结构学习 2叉树
    C++ 虚函数表解析
    数据结结构学习 线性表
    C#实现MD5加密
    学习的艺术
    C# 3.0实现类本身的方法扩展
  • 原文地址:https://www.cnblogs.com/fisherss/p/10305735.html
Copyright © 2011-2022 走看看