题意:多米诺骨牌的矩形完全覆盖, 要求统计没有横切割线和竖切割线的方案数
题解
第一部分就是轮廓线 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 的无行分割线的合法覆盖
大神的思想就是不一样,,,,,我是想不到。但是起码学到了容斥的 奇加偶减!!!!
Dominoes are rectangular tiles with nice 2 × 1 and 1 × 2 sizes. 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. Now the managers of the company wonder, how many different solid tilings exist for an m × n rectangle. Help them to find that out. Input The input file contains m and n(1≤m,n≤16) . Output Output one integer number mod 1e9+7 - the number of solid tilings of m×n rectangle with 2 × 1 and 1 × 2 pavement tiles. Sample Input 2 2 5 6 8 7 Sample Output 0 6 13514 Hint All 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; }