51nod 1033 骨牌覆盖 V2(矩阵快速幂)
2017-09-26 20:58
225 查看
骨牌覆盖 V2
思路:
这类题主要的难点就在于状态的转移,可以先看看这道题(骨牌覆盖问题·三)中的提示
dp[i][j]表示从状态i转换成状态j共有多少种方法(二进制下的01表示骨牌是否覆盖)
则m行的排法就是dp^(m+1)的值(第0行的状态为0,第m行的状态为((1<<n)-1,则需进行m+1次dp=dp*dp)
因此,我们可以先用dfs处理出状态转移的可行性,然后矩阵快速幂即可
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long LL; const int maxn=1<<5; const LL mod=1e9+7; int n,m,N,dp[maxn][maxn]; struct Matrix { LL mat[maxn][maxn]; } res,arr; void dfs(int col,int pre,int now) { if(col==n) { dp[pre][now]=1;//dp[pre][now]=1,表示能从pre状态转换到now状态 return ; } dfs(col+1,pre<<1,now<<1|1);//竖放,第col+1列由空变为放骨牌 dfs(col+1,pre<<1|1,now<<1);//不放,第col+1列由放骨牌变为空 if(col+2<=n)//横放,col+1和col+2列均放骨牌 dfs(col+2,pre<<2|3,now<<2|3); } Matrix mul(Matrix a,Matrix b) { Matrix tmp; for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) { tmp.mat[i][j]=0; for(int k=0; k<N; ++k) tmp.mat[i][j]=(tmp.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod; } return tmp; } LL pow_matrix(Matrix a) { for(int i=0; i<N; ++i) arr.mat[i][i]=1; while(m) { if(m&1) arr=mul(arr,a); a=mul(a,a); m>>=1; } return arr.mat[0][N-1]; } int main() { scanf("%d%d",&m,&n); ++m; N=1<<n; dfs(0,0,0); for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) res.mat[i][j]=dp[i][j]; printf("%lld\n",pow_matrix(res)); return 0; }
参考博客:
lastone
相关文章推荐
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 51nod 1033 骨牌覆盖 V2(矩阵快速幂)
- 点头OJ 1033 . 骨牌覆盖 V2 ( 状态压缩 + 矩阵快速幂 )
- 51Nod-1033-骨牌覆盖 V2
- 51nod 1033骨牌覆盖 V2
- 51nod 1033 骨牌覆盖v2
- 51nod 1197 字符串的数量 V2(矩阵快速幂+数论?)
- hihoCoder 1143 : 骨牌覆盖问题·一 矩阵快速幂