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
第一列对应位置相乘之和。