首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

【矩阵乘法又实践】HDU 2604——queuing

2013-02-25 
【矩阵乘法再实践】HDU 2604——queuing题目:点击打开链接首先,这是一个递推问题。mm结尾的只能由fm结尾的或者m

【矩阵乘法再实践】HDU 2604——queuing

题目:点击打开链接

首先,这是一个递推问题。mm结尾的只能由fm结尾的或者mm结尾的推来。以mf结尾的只能由mm结尾的推来,以fm结尾的只能由mf或者ff推来,以ff结尾的只能由mf推来。

F(n)=F(n-1)+F(n-3)+F(n-4)。可是正常用大数的话会TLE。后来查阅DISCUSS得知应该使用矩阵乘法。

其中1——4是已知的。

其中这个A矩阵是要构建的,一般是通过0-1阵,达到下图的目的,构阵方式不唯一。

【矩阵乘法又实践】HDU 2604——queuing

构完阵后,将目标值-4,然后进行二分幂优化,再手动把前四加上,还是稍微有点晕的,毕竟数学略拙计。。

另外附两个较为清楚的大神链接:

矩阵乘法的方法        DP的方法

#include <iostream>#include <cmath>#include <cstring>using namespace std;class Mat{public:    __int64 mat[10][10];};int n=4;     //维度,即矩阵A的行数int MOD;//好多问题要求给出取余之后的数字Mat E;int f[5]={0,2,4,6,9};void initE(){for(int i=0;i<10;i++)E.mat[i][i]=1;}Mat operator*(Mat a,Mat b){    int i,j,k;    Mat c;    for (i=0;i<n;i++)    {        for (j=0;j<n;j++)        {            c.mat[i][j] = 0;            for (k=0;k<n;k++)                c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%MOD;               c.mat[i][j]%=MOD;        }    }    return c;}Mat operator+(Mat a,Mat b){    Mat c;    int i,j;    for (i=0;i<n;i++)    {        for (j=0;j<n;j++)            c.mat[i][j] = (a.mat[i][j]+b.mat[i][j])%MOD;    }    return c;}Mat operator^(Mat a,int x)  {       Mat p = E,q = a;       while (x>=1)       {           if(x%2==1)               p = p*q;           x/=2;           q = q*q;       }       return p;  }Mat solve(Mat a,int p)   {       if(p==1)           return a;     else if(p&1)           return (a^p)+solve(a,p-1);       else           return ((a^(p>>1))+E)*solve(a,p>>1);   }     int main() { int length,mod; while(cin>>length>>MOD) { initE();Mat a;memset(a.mat,0,sizeof(a.mat)); a.mat[0][0]=a.mat[0][2]=a.mat[0][3]=a.mat[1][0]=a.mat[2][1]=a.mat[3][2]=1;  if(length<=4) { cout<<f[length]%MOD<<endl; continue; } Mat x;  x=a^(length-4);  int ans=0;  ans=(x.mat[0][0]*9+x.mat[0][1]*6+x.mat[0][2]*4+x.mat[0][3]*2); cout<<ans%MOD<<endl; } return 0; }



热点排行