ACM PKU 3420 Quad Tiling 很难的动态规划,需要灵活应用矩阵`

http://acm.pku.edu.cn/JudgeOnline/problem?id=3420
好几个人都问我这道题,可是我自己也不会做,真是惭愧啊...太落后了..别人都飞机大炮了,我还在小米加步枪.... 太羞愧了 ..

不过还好,除了Felicia的程序以外(http://www.cppblog.com/felicia/archive/2007/10/08/33740.html),我还读了两个牛人的程序.

一个是Ricky_
 1#include "stdio.h"
 2int matrix[4][4= {0,0,0,-1},
 3                     {1,0,0,1},
 4                     {0,1,0,5},
 5                     {0,0,1,1}}
;
 6int n, m;
 7int tmp[4][4], quo[4][4], ans[4];
 8
 9void MatrixCopy( int to[][4], int from[][4] ){
10     int i, j;
11     for ( i = 0; i < 4; i++ ){
12         for ( j = 0; j < 4; j++ ){
13             to[ i ][ j ] = from[ i ][ j ];
14         }

15     }
     
16}

17void MatrixMulti( int a[][4], int b[][4], int c[][4] ){
18     int i, j, k, t;
19     for ( i = 0; i < 4; i++ ){
20         for ( j = 0; j < 4; j++ ){
21             t = 0;
22             for ( k = 0; k < 4; k++ ){
23                 t = ( t + a[ i ][ k ] * b[ k ][ j ] ) % m;
24             }

25             c[ i ][ j ] = t;
26         }

27     }
     
28}

29void MatrixPow( int n ){
30     if ( n == 1 ) return;    
31     MatrixPow( n / 2 );
32     MatrixMulti( quo, quo, tmp );
33     if ( n % 2 ){
34          MatrixMulti( tmp, matrix, quo );   
35     }
 else{
36          MatrixCopy( quo, tmp );         
37     }

38}

39
40int main(){
41    int i, j, t;
42    while ( scanf("%d%d"&n, &m ) && n ){
43          ans[0]=1;ans[1]=1;ans[2]=5;ans[3]=11;
44          if ( n < 4 ){
45               printf("%d\n", ans[ n ] % m );
46               continue;   
47          }
      
48          MatrixCopy( quo, matrix );
49          MatrixPow( n - 3 );
50          t = 0;
51          for ( i = 0; i < 4; i++ ){
52              t += ans[ i ] * quo[ i ][ 3 ];
53          }

54          printf("%d\n", t % m );
55    }

56}

57


还有一个我读过的所有程序中最新颖的(当然也可能是我孤陋寡闻了),让人觉得神清气爽的! 黄强写的程序!
 1#include <stdio.h>
 2#include <memory.h>
 3int n,MOD;
 4class Mat{
 5public:
 6 int v[4][4];
 7 Mat(int x){
 8  memset(v,0,sizeof(v));
 9  if (x==1)
10   v[0][0]=v[1][1]=v[2][2]=v[3][3]=1
11  else if (x==2){
12   v[0][0]=1; v[0][1]=5; v[0][2]=1; v[0][3]=-1;
13   v[1][0]=v[2][1]=v[3][2]=1;
14  }

15 }

16 Mat friend operator * (const Mat &A,const Mat &B){   //矩阵相乘
17  Mat C(0);
18  int i,j,k;
19  for (i=0;i<4;i++)
20   for (j=0;j<4;j++{
21    for (k=0;k<4;k++)
22     C.v[i][j]=(C.v[i][j]+A.v[i][k]*B.v[k][j]%MOD)%MOD;
23    if (C.v[i][j]<0) C.v[i][j]+=MOD;
24   }

25  }

26  return C;
27 }

28}
;
29void solve() {
30 int ans;
31 Mat V(1),B(2);
32 while (n) {
33  if (n&1) V=V*B; //奇数
34  n>>=1;          //除以2
35  B=B*B;   
36 }

37 ans=11*V.v[3][0]+5*V.v[3][1]+V.v[3][2]+V.v[3][3];
38 ans%=MOD;
39 printf("%d\n",ans);
40}

41int main(){
42 while (scanf("%d%d",&n,&MOD)!=EOF && (n+MOD))
43  solve();
44 return 0;
45}

牛啊~~~
记录下来,没事就看看.这才是真正的ACM/ICPC!

posted on 2007-11-15 14:03 流牛ζ木马 阅读(1565) 评论(2)  编辑 收藏 引用

评论

# re: ACM PKU 3420 Quad Tiling 很难的动态规划,需要灵活应用矩阵` 2007-11-18 18:33 Run&Run

看不懂.能解释下吗?  回复  更多评论   

# re: ACM PKU 3420 Quad Tiling 很难的动态规划,需要灵活应用矩阵` 2007-12-11 11:00 ACLover

Ricky的程序不行啊505464 29298
521871 29931
526306 19184
511851 6808
520370 8044
507265 21718
都有错啊  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2011年10月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

公告

MY Email/MSN :mars1021@163.com QQ : 27402040 流牛ζ木马

常用链接

留言簿(6)

随笔档案

相册

搜索

最新随笔

最新评论

阅读排行榜

评论排行榜