zoukankan      html  css  js  c++  java
  • HDU

        Queuing

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


    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
     

    题意

    给定一个队伍长度k,和mod,求队伍有多少种排列可能。其中,队伍排列要求: 不能出现 fff 或者 fmf 

    解题思路

    类似递推思路, 1.若最后一个为m,则无论前一个为什么情况都可以,sum+=dp[i-1]

    若最后一个为f,则  {

                 2. 若前一位为m,则再之前一位必定为m,此时队列为mmf,此时可同第一种情况,由mmf前一位决定,此时sum+=dp[i-3]

                 3. 若前一位为f,则队伍要符合题意之前依旧只能是mm,原理同第二种情况,此时队列为mmff,由mmff前一位决定,此时sum+=dp[i-4]

              }

    得递推式,f(n)=f(n-1)+f(n-3)+f(n-4);

    之后直接矩阵快速幂即可

    则  f(n)    1 0 1 1      f(n-1)

      f(n-1)    1 0 0 0   f(n-2)

      f(n-2)       0 1 0 0  f(n-3)

        f(n-3)        0 0 1 0   f(n-4)

    手推枚举前4项,得f(1)=2  f(2)=4 f(3)=6 f(4)=9

    具体实现看代码吧

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=50;
    typedef long long ll;
    #define mod(x) ((x)%MOD)
    ll MOD;
    //2 4 6 9
    struct mat
    {
        int m[maxn][maxn];
        mat(){
            memset(m,0,sizeof(m));
        }
    }unit;
    mat operator*(mat a,mat b)
    {
        mat ret;
        ll x,n=4;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                x=0;
                for(int k=0;k<n;k++)
                {
                    x+=mod((ll)a.m[i][k]*b.m[k][j]);
                }
                ret.m[i][j]=mod(x);
            }
        }
        return ret;
    }
    void iint()
    {
        for(int i=0;i<maxn;i++)
        {
            unit.m[i][i]=1;
        }
        return ;
    }
    mat pow1(mat a,ll n)
    {
        mat ret=unit;
        while(n)
        {
            if(n&1)
            {
                n--;ret=ret*a;
            }
            n>>=1;
            a=a*a;
        }
        return ret;
    }
    int main()
    {
        ll k;
        mat b;
        b.m[0][0]=9; b.m[1][0]=6; b.m[2][0]=4;  b.m[3][0]=2;   
        //f(1)对于f(n)来说是f(n-4),这四项写反,查错了好久,哭
        while(cin>>k>>MOD)
        {
            if(k<=4) {  cout<<b.m[4-k][0]%MOD<<endl;continue;}
            iint(); //构建单位阵
            mat a;
            a.m[0][0]=a.m[0][2]=a.m[0][3]=a.m[1][0]=a.m[2][1]=a.m[3][2]=1;
            //a.m[0][1]=a.m[1][1]=a.m[1][2]=a.m[1][3]=a.m[2][0]=a.m[2][2]=a.m[2][3]=a.m[3][0]=a.m[3][1]=a.m[3][3]=0;
            a=pow1(a,k-4); //进行k-4次快速幂即可
            a=a*b;
            /*for(int i=0;i<4;i++)
            { //这是查看矩阵的= =
                for(int j=0;j<4;j++)
                {
                    if(j+1==4) cout<<a.m[i][j]<<endl;
                    else cout<<a.m[i][j]<<" ";
                }
            }*/
            cout<<mod(a.m[0][0])<<endl;
        }
        return 0;
    }

     

     
  • 相关阅读:
    洛谷 P2048 [NOI2010]超级钢琴(优先队列,RMQ)
    洛谷P1074 靶形数独(跳舞链)
    洛谷P1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
    洛谷P4003 无限之环(费用流)
    洛谷P3264 [JLOI2015]管道连接(斯坦纳树)
    洛谷P3190 [HNOI2007]神奇游乐园(插头dp)
    洛谷P3272 [SCOI2011]地板(插头dp)
    常用的端口配置
    Win7+Eclipse+Hadoop2.6.4开发环境搭建
    Windows10+eclipse+hadoop2.7.1环境配置+wordcount-折腾笔记
  • 原文地址:https://www.cnblogs.com/weimeiyuer/p/9046190.html
Copyright © 2011-2022 走看看