【HDU2604】Queuing(矩阵快速幂+递推)

题目链接

Queuing

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


 

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.

 

Sample Input

 

3 8 4 7 4 8

 

Sample Output

 

6 2 1

【题意】

有一个2^L长的队伍,队伍中有f和m,当队伍中存在fmf或fff这两种情况的子队列时该队伍为O队列,否则为E队列,求解给定长度的E队列的方案数。

【解题思路】

题解参考大佬博客:https://blog.csdn.net/jnxxhzz/article/details/83025739

假设dp[n]表示长度为n的E序列的方案数,第n个位置可以放f或m。

1.若第n个位置放m,那么第n-1个位置可以放f,m,这两种情况都不会变成O队列,所以第n-1个位置的状态可以被转移。

2.若第n个位置放f,那么第n-1个位置放f还是m不确定,因为都有可能会构成O队列。

(1)当第n-1个位置放m,那么第n-2个位置只能放m,所以第n-3个位置的状态可以被转移。

(2)当第n-1个位置放f,那么第n-2个位置只能放m,但是第n-3个位置如果放f也是会构成O队列的,所以第n-3个位置也只能放m,所以第n-4个位置的状态可以被转移。

最后f(n)=f(n-1)+f(n-3)+f(n-4),就是矩阵快速幂模板题啦。

【代码】

#include<bits/stdc++.h>
using namespace std;
int n,mod;
int f[5]={1,2,4,6,9};
struct Matrix
{
    int a[4][4];
    void init()
    {
        memset(a,0,sizeof(a));
        for(int i=0;i<4;i++)
            a[i][i]=1;
    }
};
Matrix mul(Matrix a,Matrix b)
{
    Matrix ans;
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            ans.a[i][j]=0;
            for(int k=0;k<4;k++)
                ans.a[i][j]=(ans.a[i][j]+(a.a[i][k]*b.a[k][j])%mod)%mod;
        }
    }
    return ans;
}
Matrix quick_pow(Matrix a,int n)
{
    Matrix ans;
    ans.init();
    while(n)
    {
        if(n&1)ans=mul(ans,a);
        a=mul(a,a);
        n>>=1;
    }
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&mod))
    {
        if(n<=4)
        {
            printf("%d\n",f[n]%mod);
            continue;
        }
        Matrix x;
        memset(x.a,0,sizeof(x.a));
        x.a[0][0]=x.a[0][2]=x.a[0][3]=x.a[1][0]=x.a[2][1]=x.a[3][2]=1;
        x=quick_pow(x,n-4);
        int ans=0;
        for(int i=0;i<4;i++)
        {
            int t=(x.a[0][i]*f[4-i])%mod;
            ans=(ans+t)%mod;
        }
        printf("%d\n",ans%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/83028893