POJ 3420 构造矩阵乘法
2012-04-01 08:48
330 查看
很有趣的题哈~很久以前看了matrix67大牛的相关博文,对这个题有点印象,但却不知道怎么做。
昨晚睡前构思了一下,还到老胡电脑上试敲,当然得出来的答案怪怪的。
一直记得是从0->0的方案,可是输出矩阵得出的却是15->15的方案....
下面说一下思路吧:
我们假定给出的4*N的瓷砖为
第N-2排放满有如下15种情况。0代表没有瓷砖,1代表有瓷砖
第N排 0000 0000 0000 0000 ....... 0000
第N-1排 0000 0001 0010 0011 1111
下面我们把第N-1排放满,但是N-1排不能横着放,因为N-1排横着放会引起状态的重复。
好了,下面
第N排 0000 0001 0010 0011 ...... 1111
第N-1排 1111 1111 1111 1111 1111
具体状态是怎么转移的呢??
以0000 为例
1110
在第N-1排竖着放一个-> 0001 再横着放一个 1101 0111
1111 1111 1111
这样由1110可以转变为3种状态。用二进制表示,可以得到一个状态转换图。
由1110到0001,1101,0111各有一条有向状态转换边。
这个状态矩阵转换N次幂的[1111][1111]就是求的摆法有多少种.....
Code:
昨晚睡前构思了一下,还到老胡电脑上试敲,当然得出来的答案怪怪的。
一直记得是从0->0的方案,可是输出矩阵得出的却是15->15的方案....
下面说一下思路吧:
我们假定给出的4*N的瓷砖为
第N-2排放满有如下15种情况。0代表没有瓷砖,1代表有瓷砖
第N排 0000 0000 0000 0000 ....... 0000
第N-1排 0000 0001 0010 0011 1111
下面我们把第N-1排放满,但是N-1排不能横着放,因为N-1排横着放会引起状态的重复。
好了,下面
第N排 0000 0001 0010 0011 ...... 1111
第N-1排 1111 1111 1111 1111 1111
具体状态是怎么转移的呢??
以0000 为例
1110
在第N-1排竖着放一个-> 0001 再横着放一个 1101 0111
1111 1111 1111
这样由1110可以转变为3种状态。用二进制表示,可以得到一个状态转换图。
由1110到0001,1101,0111各有一条有向状态转换边。
这个状态矩阵转换N次幂的[1111][1111]就是求的摆法有多少种.....
Code:
#include<iostream> #include<cstdio> #include<string.h> using namespace std; typedef __int64 ll; struct node { ll ma[16][16]; }; node res,temp; int N,M; int bit[4]; void init(){ memset( res.ma,0,sizeof(res.ma) ); memset( temp.ma,0,sizeof(temp.ma) ); for( int i=0;i<16;i++ ) res.ma[i][i]=1; for( int i=0;i<4;i++ ) bit[i]=(1<<i); } void set_matrix() { for( int i=0;i<16;i++ ){ temp.ma[i][(~i)&0xF]++; for( int j=0;j<3;j++ ) if( ((~i)&bit[j]&0xF)==0 && ((~i)&bit[j+1]&0xF)==0 ) temp.ma[i][((~i)|bit[j]|bit[j+1])&0xF]++; } temp.ma[15][15]++; } node matriXmult( node a,node b ) { node c; memset( c.ma,0,sizeof(c.ma) ); for( int i=0;i<16;i++ ) for( int k=0;k<16;k++ ) if( a.ma[i][k] ) for( int j=0;j<16;j++ ) c.ma[i][j]+=a.ma[i][k]*b.ma[k][j]; for( int i=0;i<16;i++ ) for( int j=0;j<16;j++ ) c.ma[i][j]%=M; return c; } void matrix_Power() { for( int i=0;i<31;i++ ) { if( N&(1<<i) ) res=matriXmult(res,temp); temp=matriXmult(temp,temp); } } int main() { while( scanf("%d%d",&N,&M)&&N|M ) { init(); set_matrix(); matrix_Power(); printf( "%I64d\n",res.ma[15][15] ); } return 0; }
相关文章推荐
- POJ 3420 矩阵乘法
- POJ-3420 Quad Tiling 状态压缩+矩阵乘法
- poj3420 Quad Tiling 矩阵乘法
- POJ 3420 Quad Tiling (矩阵乘法)
- POJ 1977 构造矩阵乘法
- POJ 3735 构造矩阵乘法
- poj 3420 Quad Tiling 【矩阵乘法】
- POJ-3420 回顾矩阵乘法解递推.再次提醒自己矩阵木有交换率.
- Blocks - POJ 3734 矩阵乘法递推
- POJ 2440 矩阵乘法
- poj 3070 Fibonacci (快速矩阵乘法)
- 线性代数(矩阵乘法):POJ 2778 DNA Sequence
- POJ 3213 矩阵乘法(优化)
- poj Cow Relays 矩阵乘法思想与floyd
- poj 3070 Fibonacci + 矩阵乘法(矩阵快速幂)
- [随机化 矩阵乘法] BZOJ 2396 神奇的矩阵 & 51Nod 1140 矩阵相乘结果的判断 & POJ 3318 Matrix Multiplication
- POJ 3233 Matrix Power Series 二分+矩阵乘法
- poj 3233 矩阵乘法(分块矩阵)
- POJ 3735 Training little cats(矩阵乘法 + 稀疏矩阵优化)——2016弱校联盟十一专场10.7(12点场)
- poj 3233 矩阵乘法经典题