关于n个tromino覆盖3*n矩形方案数递推式的推导

博客介绍了如何用递推式推导n个tromino完全覆盖3×n矩形的方案数fn,并通过分析多米诺骨牌的覆盖方式得出递推公式:fn=fn−1+2fn−2+6fn−3+fn−4−fn−6。还探讨了tromino的两种基本形态,并提供了计算fn的优化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tromino

多米诺是1×21\times 21×2的骨牌。tromino就是1×31\times 31×3的骨牌(可以弯折),有两种基本形态(可以旋转):
在这里插入图片描述


公式

nnn个tromino完全覆盖3×n3\times n3×n矩形的方案数为fnf_nfn,则对于n≥6n\geq6n6存在递推式:
fn=fn−1+2fn−2+6fn−3+fn−4−fn−6f_n=f_{n-1}+2f_{n-2}+6f_{n-3}+f_{n-4}-f_{n-6}fn=fn1+2fn2+6fn3+fn4fn6
f0=1,f1=1,f2=3,f3=10,f4=23,f5=62f_0=1,f_1=1,f_2=3,f_3=10,f_4=23,f_5=62f0=1,f1=1,f2=3,f3=10,f4=23,f5=62


推导

首先从1×21\times 21×2的多米诺的递推公式说起:

设完全覆盖2×n2\times n2×n矩形的方案数为gng_ngn,则对n≥2n\geq 2n2存在递推式:
gn=gn−1+gn−2g_n=g_{n-1}+g_{n-2}gn=gn1+gn2
g0=0,g1=1g_0=0,g_1=1g0=0,g1=1

简单推导如下:
假设当前已填满前2×i2\times i2×i块,考虑怎样填可以使得其增加任意2×j2\times j2×j块(j≤n−ij\leq n-ijni)。有两种最基本的覆盖方式:
在这里插入图片描述
之所以称为最基本的覆盖方式,是因为这两种结构是无法再进一步拆分的,而对于其他方式(如下图),都可以拆分成这二者。
所以求gng_ngn时,它的最后一组基本排列方式只能二选一,所以gn=gn−1+gn−2g_n=g_{n-1}+g_{n-2}gn=gn1+gn2

这样看来,对于tromino来说,只需要找出其所有的基本覆盖方式

首先可以得到以下1+2+5=8种:

在这里插入图片描述
但是还有另外8种较难考虑到的情况:
在这里插入图片描述

所以可以得到:fn=fn−1+2fn−2+5fn−3+(fn−4+fn−7+...)×2+(fn−5+fi−8+...)×2+(fn−6+fn−9+...)×4f_n=f_{n-1}+2f_{n-2}+5f_{n-3}+(f_{n-4}+f_{n-7}+...)\times 2+(f_{n-5}+f_{i-8}+...)\times2+(f_{n-6}+f_{n-9}+...)\times 4fn=fn1+2fn2+5fn3+(fn4+fn7+...)×2+(fn5+fi8+...)×2+(fn6+fn9+...)×4
而其中
(fn−4+fn−7+...)×2+(fn−5+fn−8+...)×2+(fn−6+fn−9+...)×4(f_{n-4}+f_{n-7}+...)\times 2+(f_{n-5}+f_{n-8}+...)\times2+(f_{n-6}+f_{n-9}+...)\times 4(fn4+fn7+...)×2+(fn5+fn8+...)×2+(fn6+fn9+...)×4显然是一个分类前缀和的统计,可以由:
fn−3=fn−4+2fn−5+5fn−6+(fn−7+fn−10+...)×2+(fn−8+fn−11+...)×2+(fn−9+fn−12+...)×4f_{n-3}=f_{n-4}+2f_{n-5}+5f_{n-6}+(f_{n-7}+f_{n-10}+...)\times 2+(f_{n-8}+f_{n-11}+...)\times2+(f_{n-9}+f_{n-12}+...)\times 4fn3=fn4+2fn5+5fn6+(fn7+fn10+...)×2+(fn8+fn11+...)×2+(fn9+fn12+...)×4
换元得到:
  (fn−4+fn−7+...)×2+(fn−5+fn−8+...)×2+(fn−6+fn−9+...)×4=fn−3−fn−4−2fn−5−5fn−6+2fn−4+2fn−5+4fn−6\ \ (f_{n-4}+f_{n-7}+...)\times 2+(f_{n-5}+f_{n-8}+...)\times2+(f_{n-6}+f_{n-9}+...)\times 4\\ =f_{n-3}-f_{n-4}-2f_{n-5}-5f_{n-6}+2f_{n-4}+2f_{n-5}+4f_{n-6}  (fn4+fn7+...)×2+(fn5+fn8+...)×2+(fn6+fn9+...)×4=fn3fn42fn55fn6+2fn4+2fn5+4fn6

代回原式得到:
fn=fn−1+2fn−2+6fn−3+fn−4−fn−6f_n=f_{n-1}+2f_{n-2}+6f_{n-3}+f_{n-4}-f_{n-6}fn=fn1+2fn2+6fn3+fn4fn6

那么推导就结束了。

下面是求解n个tromino覆盖3*n矩形方案数的代码(矩阵+特征多项式优化):

#include<bits/stdc++.h>
#define RI register
using namespace std;
const int N=4e4+100,M=6,mod=998244353;


char s[N];
int n,a[14],re[14],ans;

struct P{int t[14];}nw,b;

int c[10]={0,1,2,6,1,0,998244352};
int as[13]={1,1,3,10,23,62,170,441,1173,3127};

inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}
inline int mul(int x,int y){return 1ll*x*y%mod;}

inline void Ml(int *a,int *b)
{
	RI int i,j,val;
	memset(re,0,sizeof(re));
	for(i=0;i<7;++i)
	 for(j=0;j<7;++j)
	  re[i+j]=ad(re[i+j],mul(a[i],b[j]));
	for(i=12;i>5;--i) if(re[i]){
		val=re[i];
		for(j=0;j<6;++j)
		 re[i-6+j]=ad(re[i-6+j],mul(val,c[6-j]));
		re[i]=0;
	}
	for(i=0;i<=6;++i) a[i]=(re[i]+mod)%mod;
}

inline P fp(P a,int y)
{
	memset(nw.t,0,sizeof(nw.t));
	nw.t[0]=1;
	for(;y;y>>=1,Ml(a.t,a.t))
	 if(y&1) Ml(nw.t,a.t);
	return nw;
}

int main(){
	RI int i,j;P res;
	scanf("%s",s);
	n=strlen(s);
	reverse(s,s+n);
	if(n==1) {printf("%d\n",as[s[0]-'0']);return 0;}
	a[0]=b.t[1]=1;
	for(i=0;i<n;++i){
		if(s[i]!='0') {
			res=fp(b,s[i]-'0');
			Ml(a,res.t);
	    }
		res=fp(b,10);
		memcpy(b.t,res.t,sizeof(b.t));
	}
    for(i=0;i<6;++i) ans=ad(ans,mul(a[i],as[i]));
	printf("%d\n",ans); 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值