题意:多米诺骨牌的矩形完全覆盖,
要求统计没有横切割线和竖切割线的方案数
题解
第一部分就是轮廓线
DP
的入门裸题
预处理出任意矩形大小的方案数
RES[i][j]
不过我怀疑这部分不提前打表的过不了
第二部分是一个容斥
先对列容斥,用状压的方式枚举出所有列的分割情况
然后计算,当前列分割情况下,行没有分割的方案数
dp[n]
然后再用容斥,奇加偶减即能得出答案
而
dp[n]
的求法为,设当前分割下,宽度为 x的无限制覆盖为
cnt[x]
cnt[x]=RES[x][bsiz1]∗RES[x][bsiz2]∗...∗RES[x][bsizt]
其中
bsiz1...bsizt
为列分割线分割出的每一块的横向大小
dp[i]=cnt[i]−∑i−1j=0dp[j]∗cnt[i−j]
其中
cnt[i]
为宽度为 i的任意覆盖,
减去每一个前
j
个无行分割线,后
i−j
个有行分割线的方案
减去这些互斥的非法方案,剩下的即为宽度为
i
的无行分割线的合法覆盖
大神的思想就是不一样,,,,,我是想不到。但是起码学到了容斥的 奇加偶减!!!!
The tiling is called solid if it is not possible to split the tiled rectangle by a straight line, not crossing the interior of any tile. For example, on the picture below the tilings (a) and (b) are solid, while the tilings (c) and (d) are not.
![](https://i-blog.csdnimg.cn/blog_migrate/6f05624cff1087e610f9fc32a185e821.jpeg)
Now the managers of the company wonder, how many different solid tilings exist for an m × n rectangle. Help them to find that out.
2 2 5 6 8 7
0 6 13514HintAll solid tilings for the 5×6 rectangle are provided on the picture below:#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int mod=1e9+7; typedef long long ll; int n,m; //int dp[20][70000]; int ans[20][70000]; void init(); ll solve() { int bcnt,bsize,block[20]; int dp[20]; int res=0; for(int i=0;i<1<<(m-1);i++) { bcnt=bsize=0; for(int j=0;j<m-1;j++) { if(i&(1<<j)) { block[bcnt++]=++bsize; bsize=0; } else bsize++; } block[bcnt++]=++bsize; for(int j=1;j<=n;j++) { for(int k=0;k<j;k++) { ll cnt=1; for(int l=0;l<bcnt;l++) { cnt=(cnt*ans[j-k][block[l]])%mod; } if(k==0) dp[j]=cnt; else dp[j]=(dp[j]-cnt*dp[k])%mod; } } if(bcnt&1) res=(res+dp[n])%mod; else res=(res-dp[n])%mod; } return ((res+mod)%mod); } int main() { init();//未容斥前的铺砖总数 while(scanf("%d%d",&n,&m)!=EOF) { printf("%lld\n",solve()); } return 0; } //void dfs(int i,int j,int state,int next,int n) //{ // if(j==n) // { // dp[i+1][next]+=dp[i][state]; // dp[i+1][next]%=mod; // return; // } // if(((1<<j)&state)>0) // dfs(i,j+1,state,next,n); // if(((1<<j)&state)==0) // dfs(i,j+1,state,next|(1<<j),n); // if(j+1<n&&((1<<j)&state)==0&&(1<<(j+1)&state)==0) // dfs(i,j+2,state,next,n); //} // //void solve(int n,int m) //{ // memset(dp,0,sizeof(dp)); // dp[1][0]=1; // for(int i=1;i<=m;i++) // for(int j=0;j<(1<<n);j++) // if(dp[i][j]) // dfs(i,0,j,0,n); // ans[n][m]=dp[m+1][0]; //} // //void init() //{ // for(int i=1;i<=16;i++) // for(int j=1;j<=16;j++) // { // solve(i,j); // printf("ans[%d][%d]=%d;\n",i,j,ans[i][j]); // } //} void init() { ans[1][1]=0; ans[1][2]=1; ans[1][3]=0; ans[1][4]=1; ans[1][5]=0; ans[1][6]=1; ans[1][7]=0; ans[1][8]=1; ans[1][9]=0; ans[1][10]=1; ans[1][11]=0; ans[1][12]=1; ans[1][13]=0; ans[1][14]=1; ans[1][15]=0; ans[1][16]=1; ans[2][1]=1; ans[2][2]=2; ans[2][3]=3; ans[2][4]=5; ans[2][5]=8; ans[2][6]=13; ans[2][7]=21; ans[2][8]=34; ans[2][9]=55; ans[2][10]=89; ans[2][11]=144; ans[2][12]=233; ans[2][13]=377; ans[2][14]=610; ans[2][15]=987; ans[2][16]=1597; ans[3][1]=0; ans[3][2]=3; ans[3][3]=0; ans[3][4]=11; ans[3][5]=0; ans[3][6]=41; ans[3][7]=0; ans[3][8]=153; ans[3][9]=0; ans[3][10]=571; ans[3][11]=0; ans[3][12]=2131; ans[3][13]=0; ans[3][14]=7953; ans[3][15]=0; ans[3][16]=29681; ans[4][1]=1; ans[4][2]=5; ans[4][3]=11; ans[4][4]=36; ans[4][5]=95; ans[4][6]=281; ans[4][7]=781; ans[4][8]=2245; ans[4][9]=6336; ans[4][10]=18061; ans[4][11]=51205; ans[4][12]=145601; ans[4][13]=413351; ans[4][14]=1174500; ans[4][15]=3335651; ans[4][16]=9475901; ans[5][1]=0; ans[5][2]=8; ans[5][3]=0; ans[5][4]=95; ans[5][5]=0; ans[5][6]=1183; ans[5][7]=0; ans[5][8]=14824; ans[5][9]=0; ans[5][10]=185921; ans[5][11]=0; ans[5][12]=2332097; ans[5][13]=0; ans[5][14]=29253160; ans[5][15]=0; ans[5][16]=366944287; ans[6][1]=1; ans[6][2]=13; ans[6][3]=41; ans[6][4]=281; ans[6][5]=1183; ans[6][6]=6728; ans[6][7]=31529; ans[6][8]=167089; ans[6][9]=817991; ans[6][10]=4213133; ans[6][11]=21001799; ans[6][12]=106912793; ans[6][13]=536948224; ans[6][14]=720246619; ans[6][15]=704300462; ans[6][16]=289288426; ans[7][1]=0; ans[7][2]=21; ans[7][3]=0; ans[7][4]=781; ans[7][5]=0; ans[7][6]=31529; ans[7][7]=0; ans[7][8]=1292697; ans[7][9]=0; ans[7][10]=53175517; ans[7][11]=0; ans[7][12]=188978103; ans[7][13]=0; ans[7][14]=124166811; ans[7][15]=0; ans[7][16]=708175999; ans[8][1]=1; ans[8][2]=34; ans[8][3]=153; ans[8][4]=2245; ans[8][5]=14824; ans[8][6]=167089; ans[8][7]=1292697; ans[8][8]=12988816; ans[8][9]=108435745; ans[8][10]=31151234; ans[8][11]=940739768; ans[8][12]=741005255; ans[8][13]=164248716; ans[8][14]=498190405; ans[8][15]=200052235; ans[8][16]=282756494; ans[9][1]=0; ans[9][2]=55; ans[9][3]=0; ans[9][4]=6336; ans[9][5]=0; ans[9][6]=817991; ans[9][7]=0; ans[9][8]=108435745; ans[9][9]=0; ans[9][10]=479521663; ans[9][11]=0; ans[9][12]=528655152; ans[9][13]=0; ans[9][14]=764896039; ans[9][15]=0; ans[9][16]=416579196; ans[10][1]=1; ans[10][2]=89; ans[10][3]=571; ans[10][4]=18061; ans[10][5]=185921; ans[10][6]=4213133; ans[10][7]=53175517; ans[10][8]=31151234; ans[10][9]=479521663; ans[10][10]=584044562; ans[10][11]=472546535; ans[10][12]=732130620; ans[10][13]=186229290; ans[10][14]=274787842; ans[10][15]=732073997; ans[10][16]=320338127; ans[11][1]=0; ans[11][2]=144; ans[11][3]=0; ans[11][4]=51205; ans[11][5]=0; ans[11][6]=21001799; ans[11][7]=0; ans[11][8]=940739768; ans[11][9]=0; ans[11][10]=472546535; ans[11][11]=0; ans[11][12]=177126748; ans[11][13]=0; ans[11][14]=513673802; ans[11][15]=0; ans[11][16]=881924366; ans[12][1]=1; ans[12][2]=233; ans[12][3]=2131; ans[12][4]=145601; ans[12][5]=2332097; ans[12][6]=106912793; ans[12][7]=188978103; ans[12][8]=741005255; ans[12][9]=528655152; ans[12][10]=732130620; ans[12][11]=177126748; ans[12][12]=150536661; ans[12][13]=389322891; ans[12][14]=371114062; ans[12][15]=65334618; ans[12][16]=119004311; ans[13][1]=0; ans[13][2]=377; ans[13][3]=0; ans[13][4]=413351; ans[13][5]=0; ans[13][6]=536948224; ans[13][7]=0; ans[13][8]=164248716; ans[13][9]=0; ans[13][10]=186229290; ans[13][11]=0; ans[13][12]=389322891; ans[13][13]=0; ans[13][14]=351258337; ans[13][15]=0; ans[13][16]=144590622; ans[14][1]=1; ans[14][2]=610; ans[14][3]=7953; ans[14][4]=1174500; ans[14][5]=29253160; ans[14][6]=720246619; ans[14][7]=124166811; ans[14][8]=498190405; ans[14][9]=764896039; ans[14][10]=274787842; ans[14][11]=513673802; ans[14][12]=371114062; ans[14][13]=351258337; ans[14][14]=722065660; ans[14][15]=236847118; ans[14][16]=451896972; ans[15][1]=0; ans[15][2]=987; ans[15][3]=0; ans[15][4]=3335651; ans[15][5]=0; ans[15][6]=704300462; ans[15][7]=0; ans[15][8]=200052235; ans[15][9]=0; ans[15][10]=732073997; ans[15][11]=0; ans[15][12]=65334618; ans[15][13]=0; ans[15][14]=236847118; ans[15][15]=0; ans[15][16]=974417347; ans[16][1]=1; ans[16][2]=1597; ans[16][3]=29681; ans[16][4]=9475901; ans[16][5]=366944287; ans[16][6]=289288426; ans[16][7]=708175999; ans[16][8]=282756494; ans[16][9]=416579196; ans[16][10]=320338127; ans[16][11]=881924366; ans[16][12]=119004311; ans[16][13]=144590622; ans[16][14]=451896972; ans[16][15]=974417347; ans[16][16]=378503901; }