hihoCoder 骨牌覆盖问题·一 hiho一下 第四十一周

 

骨牌的覆盖问题:我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘。对于这个棋盘,一共有多少种不同的覆盖方法呢?

 

思路:已经在网页中给出,就是用矩阵来装下X。

 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 }
骨牌

 

你可能感兴趣的:(code)