Software Competency---Puzzles (state compression dp+ matrix fast Power)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.