hdu 2604(矩阵快速幂)

来源:互联网 发布:java手动线程池使用 编辑:程序博客网 时间:2024/05/01 10:44

Queuing

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4787    Accepted Submission(s): 2121


Problem Description
Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time.

  Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue.
Your task is to calculate the number of E-queues mod M with length L by writing a program.
 

Input
Input a length L (0 <= L <= 10 6) and M.
 

Output
Output K mod M(1 <= M <= 30) where K is the number of E-queues with length L.
 

题意:

给一个队列,每位上放一个f或者m,不能出现fff或fmf,求长度位l的队列的总数,对m取模。


思路:

令f(n)为长度位n时的种数,n位为m时都可以,即f(n-1)。当n位为f时,末尾3位有4种情况:fff,fmf,mmf,mff。前两种不符,当后3位为mmf时,后3位没有限制,即f(n-3),当后3位为mff时,fmff不行,因此后四位只能是mmff,即f(n-4)。

由此得到递推公式f(n)=f(n-1)+f(n-3)+f(n-4)

由于l较大,直接递推会超时,因此想到矩阵快速幂。


#include<iostream> #include<stdio.h> #include<math.h> #include<string.h> #include<vector> #include<queue> #include<map> #include<stack> #include<queue> #include<algorithm> using namespace std; struct mat{int mm[4][4];};int n,m;mat muti(mat a,mat b){mat c;memset(c.mm,0,sizeof(c.mm));for(int i=0;i<4;i++)//矩阵相乘for(int j=0;j<4;j++)for(int k=0;k<4;k++)c.mm[i][j]=(c.mm[i][j]+a.mm[i][k]*b.mm[k][j])%m;return c;}int fun(int x){mat ans,a;memset(a.mm,0,sizeof(a.mm));memset(ans.mm,0,sizeof(ans.mm));for(int i=0;i<4;i++)for(int j=0;j<4;j++)if(i==j)ans.mm[i][j]=1;a.mm[0][0]=a.mm[0][2]=a.mm[0][3]=a.mm[1][0]=a.mm[2][1]=a.mm[3][2]=1;//初始化while(x>0)//快速幂{if(x&1)ans=muti(ans,a);a=muti(a,a);x>>=1;}return (ans.mm[0][0]*9+ans.mm[0][1]*6+ans.mm[0][2]*4+ans.mm[0][3]*2)%m;}int main(){    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);while(scanf("%d%d",&n,&m)!=EOF){if(n==0)printf("0\n");if(n==1)printf("%d\n",2%m);if(n==2)printf("%d\n",4%m);if(n==3)printf("%d\n",6%m);if(n==4)printf("%d\n",9%m);if(n>4)printf("%d\n",fun(n-4));}    return 0;}


0 0
原创粉丝点击