题目:https://www.acwing.com/problem/content/228/
题意:有一个二维矩阵,这里只给你第一行和第一列,要你求出f[n][m],关系式有 1, f[0][m]=f[0][m-1]*10+3 2, f[n][m]=f[n-1][m]+f[n][m-1]
思路:我们可以看出这里n的范围很小 ,m的范围很大,我们直接递推过去肯定超时,线性递推超时,那么肯定要用矩阵快速幂,但是这个有事二维的
那么我们只能想下怎么改成是一维的递推式,我们可以发现n是特别小的,我们可以利用n范围小,直接存下一列都没有事
那么我们可以利用递推式简化成一下形式
这样我们就可以构造出一个关系n+2的矩阵
#include<bits/stdc++.h> #define mod 10000007 using namespace std; #define MAXN 35 typedef long long ll; struct mat { ll m[MAXN][MAXN];//矩阵结构体 }unit,g;//unit为单位矩阵,即主对角线全部为1,这样任何矩阵与单位矩阵相乘都为它本身 ll n,m; mat msub(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+=((a.m[i][k]*b.m[k][j])%mod);//取余 } ret.m[i][j]=x%mod;//取余 } } return ret; } void init_unit(){ for(int i=0;i<=n;i++){ for(int j=0;j<=n;j++){ unit.m[i][j]=0; g.m[i][j]=0; } } for(int i=n-2;i>=0;i--){ scanf("%lld",&unit.m[i][0]); } unit.m[n-1][0]=23; unit.m[n][0]=3; for(int j=n;j>=0;j--){ for(int i=0;i<=j;i++){ if(j==n-1){ g.m[i][j]=10; } else g.m[i][j]=1; } } } mat qpow(mat a,ll x)//快速幂 { mat ans=unit; while(x) { if(x&1) ans=msub(a,ans); a=msub(a,a); x>>=1; } return ans; } int main() { ll x; while(scanf("%lld%lld",&n,&m)!=EOF){ n++; init_unit(); mat x=qpow(g,m); printf("%lld\n",(x.m[0][0])%mod); } return 0; }