Queuing HDU2604

一道递推题目  

得到递推关系为  f[n]=f[n-1]+f[n-3]+f[n-4]; 

用普通的枚举算法会超时

所以要用矩阵快速幂来加速

转化为矩阵即为:  

+
1 0 1 1       F(N-1)  F(N)       
1 0 0 0  *    F(N-2)  =   F(N-1)   
0 1 0 0       F(N-3)  F(N-2)
0 0 1 0       F(N-4)  F(N-3)

   

1 0 1 1(n-4)       F(4)  F(N)       
1 0 0 0            *      F(3)  =   F(N-1)   
0 1 0 0                   F(2)  F(N-2)
0 0 1 0                   F(1)  F(N-3)

所以f(n) 为 矩阵的n-4次幂  的第一行 与已知的相乘    (n-4 为  n-3-1即可   这是差值 再加一为个数)

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int n,k;

int q[5]={0,2,4,6,9};
struct matrix{
    int arr[4][4];
};


matrix multi( matrix a,matrix b )
{
         matrix c;
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++){
            c.arr[i][j]=0;
            for(int w=0;w<4;w++)
                c.arr[i][j]=(c.arr[i][j]+a.arr[i][w]*b.arr[w][j]%k)%k;
        }
    return c;
}

int fast(matrix a,int x){
    matrix ans;
    memset(ans.arr,0,sizeof(ans.arr));
    for(int i=0;i<4;i++)ans.arr[i][i]=1;

    while(x){
        if(x&1){
            ans=multi(ans,a);
               }
        x>>=1;
        a=multi(a,a);
    }
    int sum=0;
    for(int i=0;i<4;i++)
    {
        sum+=ans.arr[0][i]*q[4-i];
        sum%=k;
    }
  return sum;
}

int main(){

   while(scanf("%d%d",&n,&k)==2)
   {
       if(n<=4){printf("%d
",q[n]%k);continue;}
       else
       {
            matrix a={1,0,1,1,1,0,0,0,0,1,0,0,0,0,1,0};
            printf("%d
",fast(a,n-4)%k);
       }
   }
    return 0;
}
View Code

矩阵还是用结构体写方便。

原文地址:https://www.cnblogs.com/bxd123/p/10347814.html