题意:
小L有1*2大小的矩形骨牌和3格大小的L型骨牌。求对于每一个2*n大小的棋盘,用这两种骨牌完全覆盖的方案数
题解:
去掉3格的L型骨牌,是个经典的矩阵加速dp,加上后转移方程
dp[i] = dp[i – 1] + dp[i – 2] + 2 * (sum[i – 3])
sum[i] = sum[i – 1] + dp[i]
小L有1*2大小的矩形骨牌和3格大小的L型骨牌。求对于每一个2*n大小的棋盘,用这两种骨牌完全覆盖的方案数
题解:
去掉3格的L型骨牌,是个经典的矩阵加速dp,加上后转移方程
dp[i] = dp[i – 1] + dp[i – 2] + 2 * (sum[i – 3])
sum[i] = sum[i – 1] + dp[i]
建一个3*3的矩阵加速即可
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
#define Mod 1000000007
LL n;
struct Rec{
LL m[5][5];
};
Rec Mul(Rec u,Rec v){
Rec r;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
r.m[i][j]=0;
for(int k=0;k<5;k++){
r.m[i][j]+=(u.m[i][k]*v.m[k][j]);
r.m[i][j]%=Mod;
}
}
}
return r;
}
LL Quick(LL n){
if(n == 1)return 1;
if(n == 2)return 2;
n-=2;
Rec u,t;
memset(t.m,0,sizeof(t.m));
u.m[0][0]=1,u.m[0][1]=1,u.m[0][2]=1,u.m[0][3]=0,u.m[0][4]=0;
u.m[1][0]=1,u.m[1][1]=0,u.m[1][2]=1,u.m[1][3]=0,u.m[1][4]=0;
u.m[2][0]=0,u.m[2][1]=0,u.m[2][2]=1,u.m[2][3]=1,u.m[2][4]=0;
u.m[3][0]=0,u.m[3][1]=0,u.m[3][2]=0,u.m[3][3]=0,u.m[3][4]=1;
u.m[4][0]=2,u.m[4][1]=0,u.m[4][2]=2,u.m[4][3]=0,u.m[4][4]=0;
t.m[0][0]=2,t.m[0][1]=1,t.m[0][2]=4,t.m[0][3]=2,t.m[0][4]=1;
while(n){
if(n&1)t=Mul(t,u);
u=Mul(u,u);
n>>=1;
}
return t.m[0][0];
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%lld",&n);
printf("%lld\n",Quick(n));
}
}