• [HDU2604]Queuing


    题目:Queuing

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604

    分析:

    1)将当前格和上一格合并当作一个状态,考虑下一个格子放0(m)还是1(f).

    构造转移矩阵

    $left[ egin{array}{ccccc} . & 00 & 01 & 10 & 11 \ 00 & 1 & 1 & 0 & 0 \ 01 & 0 & 0 & 1 & 1 \ 10 & 1 & 0 & 0 & 0 \ 11 & 0 & 0 & 1 & 0 end{array} ight] $

    2)假设第一格前还有两格,为00。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    typedef long long LL;
    int MOD;
    struct Matrix{
        LL a[4][4];
        void init(int f){
            memset(a,0,sizeof a);
            if(f==-1)return;
            for(int i=0;i<4;++i)a[i][i]=1;
        }
    };
    Matrix operator*(Matrix& A,Matrix& B){
        Matrix C;C.init(-1);
        for(int i=0;i<4;++i)
        for(int j=0;j<4;++j)
            for(int k=0;k<4;++k){
                C.a[i][j]+=A.a[i][k]*B.a[k][j];
                C.a[i][j]%=MOD;
            }
        return C;
    }
    Matrix operator^(Matrix A,int n){
        Matrix Rt;Rt.init(0);
        for(;n;n>>=1){
            if(n&1)Rt=Rt*A;
            A=A*A;
        }
        return Rt;
    }
    int main(){
        int n;
        Matrix A,T;
        T.a[0][0]=T.a[0][1]=1;T.a[0][2]=T.a[0][3]=0;
        T.a[1][0]=T.a[1][1]=0;T.a[1][2]=T.a[1][3]=1;
        T.a[2][0]=1;T.a[2][1]=T.a[2][2]=T.a[2][3]=0;
        T.a[3][0]=T.a[3][1]=0;T.a[3][2]=1;T.a[3][3]=0;
        for(;~scanf("%d%d",&n,&MOD);){
            A=T^n;
            LL ans=A.a[0][0]+A.a[1][0]+A.a[2][0]+A.a[3][0];
            printf("%lld
    ",ans%MOD);
        }
    
        return 0;
    }
            

    学到了一种很有趣的递推思路。

    3)设f(i)为字符串长度为i时符合条件的字符串个数。枚举最后几位字符。

    4)当最后一个字符为0 (m)时前n-1个字符没有限制,即为f(n-1);

    当最后一个字符为1(f)时要考虑不满足的情况,那考虑最后两个字符为01(mf)和11(ff)的情况,显然要继续考虑。最后3个字符为101(fmf)、111(fff)显然不满足条件,最后3个字符为001(mmf),前n-3个字符没有限制,最后三个字符为011则要继续考虑,最后四个字符为0011,前n-4个字符没有限制,最后4个字符为1011不满足条件。综上f(n)=f(n-1)+f(n-3)+f(n-4)

    数列:f(0)=1、f(1)=2、f(2)=4、f(3)=6、f(4)=9、f(5)=15 ...

    添加一下:f(-1)=1、f(-2)=1、f(-3)=0;

    5)构造矩阵

    $left[ egin{array}{cccc} 0 & 0 & 0 & 1 \ 1 & 0 & 0 & 1 \ 0 & 1 & 0 & 1 \ 0 & 0 & 1 & 1 end{array} ight] $

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    typedef long long LL;
    int MOD;
    struct Matrix{
        LL a[4][4];
        void init(int f){
            memset(a,0,sizeof a);
            if(f==-1)return;
            for(int i=0;i<4;++i)a[i][i]=1;
        }
    };
    Matrix operator*(Matrix& A,Matrix& B){
        Matrix C;C.init(-1);
        for(int i=0;i<4;++i)
        for(int j=0;j<4;++j)
            for(int k=0;k<4;++k){
                C.a[i][j]+=A.a[i][k]*B.a[k][j];
                C.a[i][j]%=MOD;
            }
        return C;
    }
    Matrix operator^(Matrix A,int n){
        Matrix Rt;Rt.init(0);
        for(;n;n>>=1){
            if(n&1)Rt=Rt*A;
            A=A*A;
        }
        return Rt;
    }
    int main(){
        int n;
        Matrix A,T;
        T.a[0][0]=T.a[0][1]=T.a[0][2]=0;T.a[0][3]=1;
        T.a[1][0]=1;T.a[1][1]=T.a[1][2]=0;T.a[1][3]=1;
        T.a[2][0]=0;T.a[2][1]=1;T.a[2][2]=T.a[2][3]=0;
        T.a[3][0]=T.a[3][1]=0;T.a[3][2]=T.a[3][3]=1;
        for(;~scanf("%d%d",&n,&MOD);){
            A=T^n;
            LL ans=A.a[1][3]+A.a[2][3]+A.a[3][3];
            printf("%lld
    ",ans%MOD);
        }
    
        return 0;
    }
            
  • 相关阅读:
    Android中获取屏幕高度和宽度
    Android--第三方控件--okHttp
    Android中获取手机电量信息
    Android中获取并设置屏幕亮度
    ViewPager实现图片的轮播
    ScrollView嵌套使用ListView冲突的解决与分析
    Vue中的MVVM框架
    vue(一)
    RabbitMQ消费端ACK与重回队列机制,TTL,死信队列详解(十一)
    RabbitMQ消费端限流策略(十)
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/10039987.html
Copyright © 2020-2023  润新知