zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 焦作赛区网络预赛 Poor God Water 矩阵快速幂

    题目链接:Poor God Water 

    题意:有N个小时,有三种食物(用1 ,2 ,3代替好了),每个小时要吃一种食物,要求任意连续三个小时不能出现111,222,333,132,231,313,323

    的方案数

    题解:dp[i][j]表示最后两种食物分别为i,j的方案数,转移就是在增加一种食物,可以根据要求推出下面的递推矩阵.

    然后就可以用矩阵快速幂了。然后我还加了个离线的小优化(50ms)。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int mod=1e9+7;
    int n;
    int an[1005];
    struct  que
    {
        ll x;
        int id;
        bool operator<(const que b)const
        {
            return x<b.x;
        }
    }q[1005];
    struct mat
    {
        int n, m;
        ll a[15][15];
        mat() {}
        void init(int _n, int _m)
        {
            n = _n;
            m = _m;
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < m; j++) a[i][j] = 0;
            }
        }
        void one()
        {
            init(2,2);a[0][0]=1;a[1][1]=1;
        }
        mat operator + (const mat &B)const
        {
            mat C;
            C.init(n,m);
            for(int i=0; i<n; i++)
                for(int j=0; j<m; j++)
                    C.a[i][j]=(a[i][j]+B.a[i][j])%mod;
            return C;
        }
        mat operator*(const mat &P)const
        {
            mat ret;
            ret.init(n,m);
            for(int i = 0; i < n; i++)
            {
                for(int k = 0; k < m; k++)
                {
                    if(a[i][k])
                    {
                        for(int j = 0; j < P.m; j++)
                        {
                            ret.a[i][j] = ((ll)a[i][k] * P.a[k][j] + ret.a[i][j]) % mod;
                        }
                    }
                }
            }
            return ret;
        }
        mat operator^(const ll &P)const
        {
            ll num = P;
            mat ret, tmp = *this;
            ret.init(n,m);
            for(int i = 0; i < n; i++) ret.a[i][i] = 1;
            while(num)
            {
                if(num & 1) ret = ret * tmp;
                tmp = tmp * tmp;
                num >>= 1;
            }
            return ret;
        }
        void view()
        {
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    printf("%lld ",a[i][j]);
                }printf("
    ");
            }
        }
    }ap,ac,ad;
    void init()
    {
        ac.init(9,9);
        ac.a[3][0]=1;ac.a[6][0]=1;
        ac.a[0][1]=1;ac.a[3][1]=1;ac.a[6][1]=1;
        ac.a[0][2]=1;ac.a[3][2]=1;
        ac.a[1][3]=1;ac.a[4][3]=1;ac.a[7][3]=1;
        ac.a[1][4]=1;ac.a[7][4]=1;
        ac.a[1][5]=1;ac.a[4][5]=1;
        ac.a[2][6]=1;ac.a[8][6]=1;
        ac.a[5][7]=1;ac.a[8][7]=1;
        ac.a[2][8]=1;ac.a[5][8]=1;
        ad.init(9,9);
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
               ad.a[i][j]=ac.a[i][j];
            }
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        init();
        for(int i=1;i<=T;i++)
        {
            scanf("%lld",&q[i].x);
            q[i].id=i;
        }
        sort(q+1,q+T+1);
        ll p=3;
        for(int i=1;i<=T;i++)
        {
            if(q[i].x==1)
            {
                an[q[i].id]=3;
            }
            else if(q[i].x==2)
            {
                an[q[i].id]=9;
            }
            else
            {
                ad=ad*(ac^(q[i].x-p));
                p=q[i].x;
                ll ans=0;
                ap.init(1,9);
                for(int i=0;i<9;i++)
                {
                    ap.a[0][i]=1;
                }
                ap=ap*ad;
                for(int i=0;i<9;i++)
                {
                    ans+=ap.a[0][i];
                    ans%=mod;
                }
                an[q[i].id]=ans;
            }
        }
        for(int i=1;i<=T;i++)
        {
            printf("%d
    ",an[i]);
        }
    }
  • 相关阅读:
    win7桌面的文件路径是否可以更改
    win10怎么更新flash到最新版本【系统天地】
    centos7 lnmp环境部署
    thinkphp5 部署注意事项
    linux下导入、导出mysql数据库命令的实现方法
    Centos7 系统下怎么更改apache默认网站目录
    centos7 配置lamp 环境
    Redis笔记(4)独立功能的实现
    Redis笔记(3)多数据库实现
    Redis笔记(2)单机数据库实现
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9651816.html
Copyright © 2011-2022 走看看