Test instructions: Given N*m's chessboard (1<=n<=10^15, 1<=m<=7), use the L-type Domino (the tin font arbitrarily remove a port) completely cover it, ask how many kinds of solutions.
Idea: The range of M is only 1<=m<=7, obviously the pressure DP. But the maximum value of N to 10^15, can only use the fast power.
Status means: 0 is left blank, 1 means it is filled here. The 01 sequence is compressed into an int to represent the fill of a row. (for example, a status of 4 means 100, that is, the first column is filled, and the second column is three empty)
Boundary conditions:
which
t = 2^m
Represents the total number of scenarios in which the first i-1 line is filled, and the first row is placed in state S.
On behalf of the previous line where the state S2 was originally placed, the current line placed the domino to fill the previous row and make the current line status S1 the number of scenarios.
So the question is, how to get the Matrix d?
I enumerate the previous line of state S2, DFS for each s2: scan each bit of the S2 in turn, and if there is an empty location, try to visit a domino in a direction (obviously a total of 4 directions). When all the positions of the S2 are filled, the S1 is generated, so increase by 1 (initially 0).
With the Matrix D, Dark is not afraid!
Obviously there are
The matrix is quickly idempotent, and the final output is the result.
The topic itself is not much difficult, all blame my pressure DP did not learn, did this problem finally to understand some misunderstanding.
Obviously there are many things to be busy, but see this kind of thing is want to do, for a long time no such pure feeling.
The following code is attached
#include <cstdio> #include <cstring> #include <iostream>using namespace std;typedef long Long ll;const int mod = 1000000007;const int maxn = 130;int Off[5]={0,1,1,2,2};int D[MAXN][MAXN]; LL N;int M; n Rows M-column int maxs; Total number of States 1<<minline void Int2arr (int num,bool arr[])//Digital to matrix {for (int i=0;i<m;++i,num>>=1) arr[m-i-1] = Nu m&1;} inline int Arr2int (bool arr[])//matrix to number {int num = 0; for (int i=0;i<m; (num<<=1) |=arr[i++]); return num;} BOOL sbuf[2][10];inline bool Check (int cur,int type)//determines if the type direction of the domino {if (type = = 1) can be placed in the cur position return sbuf[0][cur]==0 &A mp;& sbuf[1][cur]==0 && cur+1<m && sbuf[1][cur+1]==0; if (type = = 2) return sbuf[0][cur]==0 && sbuf[1][cur]==0 && cur-1>=0 && sbuf[1][cur-1]==0; if (type = = 3) return sbuf[0][cur]==0 && sbuf[1][cur]==0 && cur+1<m && sbuf[0][cur+1]==0; if (type = = 4) return sbuf[0][cur]==0 && cur+1<m && sbuf[0][cur+1]==0 && sbuf[1][cur+1]==0;} inline void putblock (int cur,int type,int cont)//The Domino {if (type = = 1) cur] = Sbuf[1][cur in the sbuf[1][cur+1 position of the type direction = Cont ; if (type = = 2) sbuf[1][cur] = sbuf[1][cur-1] = cont; if (type = = 3) sbuf[1][cur] = cont; if (type = = 4) sbuf[1][cur+1] = cont;} void dfs (int cur)//dfs Not much explanation {if (cur >= M) {++d[arr2int (sbuf[1])][arr2int (sbuf[0])]; Return } if (sbuf[0][cur]==1) DFS (cur+1);//If the current position is filled, continue to try the next column for (int i=1;i<=4;++i) if (check (cur,i))//If the current position can be placed in the I direction Domino { Putblock (cur,i,1);//try to place the I direction Domino DFS (Cur+off[i]);//Continue to try the following column putblock (cur,i,0);//Undo Place I direction Domino}}inline void getd ( )//Compute matrix d{maxs = 1<<m; Memset (d,0,sizeof (d)); for (int i=0;i<maxs;++i) Int2arr (i,sbuf[0]), DFS (0);} inline void matmult (int a[maxn][maxn],int B[MAXN][MAXN])//matrix multiplication a*=b{static int c[maxn][maxn]; Memset (C,0,sizeof (c)); for (int i=0;i<maxs;++i) for (int j=0;j<maxs;++j) for (int k=0;k<maxs;++k) c[i][j] = (C[i][j] +(LL) A[i][k] * (LL) b[k][j])% mod)% MoD; memcpy (A,c,sizeof (c)); void matpower (int a[maxn][maxn],ll p)//matrix fast power a^p{int ANS[MAXN][MAXN]; memset (ans,0,sizeof (ans)); for (int. i=0;i<maxs;++i) Ans[i][i]=1;//ans=1 for (;p; P>>=1,matmult (A,a)) if (p&1) Matmult (ans,a);//ans* =a; A*=a; memcpy (a,ans,sizeof (ans)); return Ans}int Main () {cin>>n>>m; GETD (); Matpower (D,n); cout<< d[maxs-1 [maxs-1] <<endl; return 0;} /* Dominoes in all directions and their corresponding number 1 * * * 2 * * * 3 * * 4 * * **/
Software Competency---Puzzles (state compression dp+ matrix fast Power)