Welcome, Guest! Sign Up RSS

Clever Space

Friday, 11.22.2024
Main » 2013 » October » 8 » 多米诺难题
1:03 PM
多米诺难题

状态压缩dp+矩阵加速

#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5
using namespace std;
typedef long long LL;
int m,n,p;
struct matrix
{
  int Matrix[32][32];
  matrix operator*(const matrix b)
  {
    int i,j,k;
    matrix c;
    memset(c.Matrix,0,sizeof(c.Matrix));
    for (i=0;i<(1<<m);i++)
     for (j=0;j<(1<<m);j++)
      for (k=0;k<(1<<m);k++)
       c.Matrix[i][j]=((Matrix[i][k]*b.Matrix[k][j])%p+c.Matrix[i][j])%p;
    return c;
  }
  matrix power(int x)
  {
    if (x<2) return *this;
    matrix mt=power(x/2);
    if (x%2) return mt*mt*(*this);
    else return mt*mt;
  }
};
matrix m1;
int anstot=0;
int t[32];
void DFS(int a,int F0)
{
  m1.Matrix[a][F0]=1;
  int i;
  for (i=0;i<m-1;i++)
   if ((F0+(3<<i))==(F0|(3<<i))) DFS(a,F0+(3<<i));
  return;
}
void DFS0(int F0)
{
  t[F0]=1;
  int i;
  for (i=0;i<m-1;i++)
   if ((F0+(3<<i))==(F0|(3<<i))) DFS0(F0+(3<<i));
  return;
}
void init(int a)
{
  int cnt=m+1,i,tot,F0=0,att=a,f[7];
  memset(f,0,sizeof(f));
  while (a>0){cnt--;f[cnt]=a%2;a/=2;} 
  for (i=1;i<=m;i++) tot+=f[cnt];
  if (tot==m){m1.Matrix[a][0]=1;return;}
  for (i=1;i<=m;i++)
   if (f[i]==0) F0+=1<<(m-i);
  DFS(att,F0);
}
int main()
{
  cin>>n>>m>>p;
  memset(m1.Matrix,0,sizeof(m1.Matrix));
  memset(t,0,sizeof(t));
  int i;
  for (i=0;i<(1<<m);i++) init(i);
  DFS0(0);
  cout<<m1.power(n).Matrix[(1<<m)-1][(1<<m)-1]<<endl;
  return 0;
}

Views: 269 | Added by: dhy0077 | Rating: 5.0/1
Total comments: 0
Only registered users can add comments.
[ Sign Up | Login ]