矩阵二分快速幂优化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;
} 
原文地址:https://www.cnblogs.com/fisherss/p/10305735.html