标签:
骨牌,一种古老的玩具。今天我们要研究的是骨牌的覆盖问题:
我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘。对于这个棋盘,一共有多少种不同的覆盖方法呢?
举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式:
第1行:1个整数N。表示棋盘长度。1≤N≤100,000,000
第1行:1个整数,表示覆盖方案数 MOD 19999997
62247088
17748018
http://hihocoder.com/contest/hiho41/problem/1
思路已经在网页中给出,就是用矩阵来装下X。暂时就这样吧,被一个小bug搞得几小时,f**k!就是在那个用n&1的地方,照这样写会出问题,而用一个常量来代替就没事了,为什么?
1 #include <iostream> 2 using namespace std; 3 const int yu = 19999997; 4 const int MASK = 1; 5 struct fuf 6 { 7 long long a,b, //矩阵如左 8 c,d; 9 }q[33]; 10 11 int handle_it() 12 { 13 q[0].a=0; q[0].b=1; q[0].c=1; q[0].d=1; //矩阵M的1次方 14 int i=1; 15 for(; i<=32; i++) //作乘 16 { 17 q[i].a = ( q[i-1].a * q[i-1].a + q[i-1].b * q[i-1].c )%yu; 18 q[i].b = ( q[i-1].a * q[i-1].b + q[i-1].b * q[i-1].d )%yu; 19 q[i].c = ( q[i-1].c * q[i-1].a + q[i-1].d * q[i-1].c )%yu; 20 q[i].d = ( q[i-1].c * q[i-1].b + q[i-1].d * q[i-1].d )%yu; 21 } 22 return 0; 23 } 24 int main() 25 { 26 handle_it(); 27 int n; 28 while( cin>>n ) 29 { 30 if( n>0 && n<=3) {cout<<n<<endl;continue;} 31 int i=0; 32 while( (n&MASK)==0 ) //直到n后面的0被去掉 33 { 34 i++; 35 n >>= 1; 36 } 37 fuf ans = q[i++]; 38 n >>= 1; 39 for( ; i<32 && n!=0; i++,n >>= 1) 40 { 41 if( (n&1)==1 ) 42 { 43 fuf tmp; 44 tmp.a = ( ans.a * q[i].a + ans.b * q[i].c )%yu; 45 tmp.b = ( ans.a * q[i].b + ans.b * q[i].d )%yu; 46 tmp.c = ( ans.c * q[i].a + ans.d * q[i].c )%yu; 47 tmp.d = ( ans.c * q[i].b + ans.d * q[i].d )%yu; 48 ans = tmp; 49 } 50 } 51 cout<<ans.d<<endl; 52 } 53 return 0; 54 }
hihoCoder 骨牌覆盖问题·一 hiho一下 第四十一周
标签:
原文地址:http://www.cnblogs.com/xcw0754/p/4423691.html