您的位置:首页 > 其它

POJ-3420 回顾矩阵乘法解递推.再次提醒自己矩阵木有交换率.

2012-04-01 17:35 417 查看
HDOJ-1992的升级版(/article/2097179.html)..先推出递推公式(其实那时候我做1992这题没推出递推公式..只找到了规律打了个表..囧.刚才重新整理了一下得出递推公式...)..然后再用矩阵乘法求解..递推公式为:

T [ n ] = T [n-1]+5*T[n-2]+T[n-3]-T[n-4]

值得再次注意的是矩阵木有交换率...最后和初值矩阵做积时一定要注意顺序...

Program:

#include<iostream>  
#include<string.h>  
#include<stdio.h>  
#include<map>  
using namespace std;  
struct node
{
      int s[5][5];
}h,a,temp,T,_2M[32];
int n,m;
node Matrix_Mul(node a,node b)
{
      int k,i,j;
      memset(temp.s,0,sizeof(temp.s));
      for (k=0;k<4;k++)
         for (i=0;i<4;i++)
            for (j=0;j<4;j++)
               temp.s[i][j]=(temp.s[i][j]+a.s[i][k]*b.s[k][j])%m;
      return temp;
}
void Output_Matrix(node a)
{
      int i,j;
      for (i=0;i<4;i++)
      {
            for (j=0;j<4;j++) printf("%d ",a.s[i][j]);
            printf("\n");
      }
      printf("---------------------\n");
      return;
}
node getmatrix(node h,int l)
{
      int i,k,p;
      k=1;
      _2M[0]=h;
      for (p=1;p<=30;p++)
      {
             _2M[p]=Matrix_Mul(_2M[p-1],_2M[p-1]);
             k*=2;
             if (k>l) break;
      }
      memset(T.s,0,sizeof(T.s));
      for (i=0;i<4;i++) T.s[i][i]=1;
      while (l)
      {
             while (k>l)
             {
                   k/=2;
                   p--;
             }
             T=Matrix_Mul(T,_2M[p]);
             l-=k;
      }
      //Output_Matrix(T);
      return T;
}
int main()  
{  
      int i;
      node p;
      memset(a.s,0,sizeof(a.s));
      a.s[0][0]=1; a.s[1][0]=5; a.s[2][0]=11; a.s[3][0]=36;
      memset(h.s,0,sizeof(h.s));
      for (i=0;i<3;i++) h.s[i][i+1]=1;
      h.s[3][0]=-1; h.s[3][1]=1; h.s[3][2]=5; h.s[3][3]=1;
      while (~scanf("%d%d",&n,&m))
      {
             if (!n && !m) break;
            // Output_Matrix(a);
             p=Matrix_Mul(getmatrix(h,n-1),a); 
            // Output_Matrix(p);
             printf("%d\n",p.s[0][0]);
      }
      return 0;  
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: