题意:
求拼图的方案总数
题解:
状压DP+快速幂
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=1e9+7,maxn=1e15+5,maxm=(1<<7)+5;
ll n,m,maxState;
struct Matrix{
ll mp[maxm][maxm];
void init_one() {
ll i,j;
for (i=0;i<maxState;i++){
for (j=0;j<maxState;j++){
if(i==j)mp[i][j]=1;
else mp[i][j]=0;
}
}
}
friend Matrix operator*(Matrix a,Matrix b){
Matrix res;
int i,j,k;
for (i=0;i<maxState;++i){
for (j=0;j<maxState;++j){
res.mp[i][j]=0;
for (k=0;k<maxState;++k){
res.mp[i][j]=(res.mp[i][j]+a.mp[i][k]*b.mp[k][j]%MOD)%MOD;
}
}
}
return res;
}
friend Matrix operator^(Matrix a,ll b){
Matrix ans;
ans.init_one();
while(b){
if(b&1)ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
};
Matrix a;
bool Empty(int i,int state){
if(i<0||i>=m)return false;
if((1<<i)&state)return false;
return true;
}
void dfs(ll col,ll state,ll next){
ll tmp;
if(col==m){
a.mp[state][next]++;
a.mp[state][next]%=MOD;
return;
}
if(!Empty(col,state))dfs(col+1,state,next);
else{
if((col-1>=0)&&Empty(col-1,next)&&Empty(col,next)){
tmp=next;tmp|=(1<<col);tmp|=(1<<(col-1));
dfs(col+1,state,tmp);
}
if((col+1<m)&&Empty(col,next)&&Empty(col+1,next)){
tmp=next;tmp|=(1<<col);tmp|=(1<<(col+1));
dfs(col+1,state,tmp);
}
if((col+1<m)&&Empty(col+1,state)&&Empty(col+1,next)){
tmp=next;tmp|=(1<<(col+1));
dfs(col+2,state,tmp);
}
if((col+1<m)&&Empty(col+1,state)&&Empty(col,next)){
tmp=next;tmp|=(1<<col);
dfs(col+2,state,tmp);
}
}
}
int main(){
ll i,j;
while(scanf("%lld%lld",&n,&m)!=EOF){
maxState=(1<<m);
memset(a.mp,0,sizeof(a.mp));
for (i=0;i<maxState;i++)dfs(0,i,0);
a=a^n;
printf("%lld\n",a.mp[0][0]);
}
return 0;
}