HDU 1757 A Simple Math Problem 矩阵相乘

该题搞了一个晚上才A了它,刚开始一直不能出正确结果,总认为是我的二分哪里错了,修改了几个小时,还重敲了,后来才发现是矩阵建反了,该题最重要的是建立矩阵,如果矩阵建立好了,就万事顺利了,怎样建立这个矩阵了,我们来讨论一下(n>10),f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

我们来看个图:、

矩阵A                                                   矩阵B

0 1 0 0 0 0 0 0 0 0                                  f0                                  f1

0 0 1 0 0 0 0 0 0 0                                  f1                                  f2

0 0 0 1 0 0 0 0 0 0                                  f2                                  f3

0 0 0 0 1 0 0 0 0 0                *                f3  ---------->                f4

0 0 0 0 0 1 0 0 0 0                                  f4                                  f5

0 0 0 0 0 0 1 0 0 0                                  f5                                  f6

0 0 0 0 0 0 0 1 0 0                                  f6                                  f7

0 0 0 0 0 0 0 0 1 0                                  f7                                  f8

0 0 0 0 0 0 0 0 0 1                                  f8                                  f9

a9 a8 a7 a6 a5 a4 a3 a2 a1 a0                  f9                                  f10

我们看到规律了,每次要到下次个A*B,以此类推则由A*A*A.......A*B;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int num[33][11][11],count;
void Matrix( int t, int m ) //二分法
{
   if( t==1 )
      return ;
   Matrix( t/2,m );
   if( t%2 )//奇数
   {
       int number[11][11]={0};
       count++; 
       for( int i=1; i<=10; i++ )
         for( int j=1; j<=10; j++ )
           for( int k=1; k<=10; k++ )
             num[count][i][j]=(num[count][i][j]+num[count-1][i][k]*num[count-1][k][j])%m;
          for( int i=1; i<=10; i++ )
            for( int j=1; j<=10; j++ )
               for( int k=1; k<=10; k++ )
                  number[i][j]=(number[i][j]+num[count][i][k]*num[1][k][j])%m;
       for( int i=1; i<=10; i++ )
       {
          for( int j=1; j<=10; j++ )
          {
           num[count][i][j]=number[i][j];
           }
       }
   }
   else//偶数
   {
      count++; 
       for( int i=1; i<=10; i++ )
       {
         for( int j=1; j<=10; j++ )
         {
           for( int k=1; k<=10; k++ )
             num[count][i][j]=(num[count][i][j]+num[count-1][i][k]*num[count-1][k][j])%m;    
         }
       } 
   }     
}
int main()
{
    int t,m;
    while( scanf( "%d%d",&t,&m )!=EOF )
    {
        memset( num,0,sizeof( num ) );
        for( int i=1; i<=9; i++ )//建立矩阵
        {
          num[1][i][i+1]=1;
        }
       
        for( int i=10;i>=1; i-- )
          scanf( "%d",&num[1][10][i] ); 
        if( t<10 )
            printf( "%d\n",t );
        else 
          {
              count=1;
              Matrix( t-9,m );
              int sum=0;
              for( int i=1; i<=10; i++ )
              {
                    sum=(sum+num[count][10][i]*(i-1))%m;
              }
              printf( "%d\n",sum );
          }       
    }
    return 0;    
}

  

posted @ 2011-08-09 10:00  wutaoKeen  阅读(541)  评论(0编辑  收藏  举报