矩阵快速幂

1.根据递推公式写出矩阵

矩阵的乘法:C[i][j] = A矩阵中第i行与B矩阵中第j列对应位置的乘积之和
即 C[i][j] = A[i][k] * B[k][j] (1<=k<=n)
例如:f(n)=f(n-1)+2*f(n-2)+3*f(n-3)
推导出↓

1 2 3	f(n-1)	 f(n)
1 0 0 * f(n-2) = f(n-1)
0 1 0	f(n-3)	 f(n-2)

(T矩阵) (An-1)	 (An)

矩阵的第一行就是递推公式
下面几行只要满足右边矩阵即可,即需要的就 填 1,不需要的就 填 0

2.推导得到通项公式

1 2 3	f(3)	 f(4)
1 0 0 * f(2)  =  f(3)
0 1 0	f(1)	 f(2)

(T矩阵) (A3)	 (A4)

i = 1:T^1 * A3 = A(4)
i = 2:T^2 * A3 = A(5)

i = n:T^n * A3 = A(3+n)
题目要求的为An
易得:T^(n-3) * A3 = An
所以只需要将快速幂的底数换成矩阵求出T^(n-3)就行了

3.套入矩阵快速幂模板

public class MatrixDemo {
	public static void main(String[] args) {
		long[][] matrix = new long[2][2];
		matrix[0][0] = 2;matrix[0][1] = 2;
		matrix[1][0] = 2;matrix[1][1] = 2;
		int mod = (int)1e9+7;
		//2*2矩阵的3次方测试
		matrix = pow(3,2,matrix,mod);
		for(int i=0;i<2;i++) {
			for(int j=0;j<2;j++) {
				System.out.print(matrix[i][j]+" ");
			}
			System.out.println();
		}
	}
	//a第一个矩阵,b第二个矩阵,n矩阵的长度,mod取余
	public static long[][] mul(long[][] a,long[][] b,int n,int mod){
		long result[][] = new long[n][n];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				for(int k=0;k<n;k++) {
					result[i][j] += ((a[i][k]*b[k][j])%mod);
					result[i][j] %= mod;
				}
			}
		}
		return result;
	}
	//k次方数,n矩阵长度,matrix即T矩阵也就是充当底数的矩阵,mod取余
	public static long[][] pow(int k,int n,long[][] matrix,int mod){
		long[][] T = new long[n][n];//T数组为充当底数的矩阵
		long[][] result = new long[n][n];//result数组为答案矩阵
		//初始化result使成为单位矩阵(对角线为1)
		for(int i=0;i<n;i++) result[i][i] = 1;
		
		T = matrix;
		
		while(k>0) {
			if((k&1) == 1) result = mul(result,T,n,mod);
			//底数乘底数
			T = mul(T,T,n,mod);
			//指数除2
			k>>=1;
		}
		return result;
	}
}

结果:
在这里插入图片描述

4.计算得到题目要求的答案

题目要求An,即求T^(n-3)的第一行和A3第一列对应位置相乘之和。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值