• L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛)


    题意:有肉,鱼,巧克力三种食物,有几种禁忌,对于连续的三个食物,1.这三个食物不能都相同;2.若三种食物都有的情况,巧克力不能在中间;3.如果两边是巧克力,中间不能是肉或鱼,求方案数

    题解:听其他队说用杜教BM 就可以过 ????  orz orz

    我发现自己不一样啊!!! 

    我用的是矩阵快速幂,将meat ,  chocolate,fish 用 0 ,1 , 2 表示

    对于 n 来说,我们只关注后两位,因为 若 n - 1 的所有方案解决的话,我们在 n - 1 的方案添加0, 1,2 就行,然后根据禁忌 去除不可能的

     我们根据次状态 来更新现状态,然后矩阵快速幂

      

    AC code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    
    const int N=9;
    struct Matrix{
        ll matrix[N][N];
    };
    
    const int mod = 1e9 + 7;
    
    void init(Matrix &res)
    {
        memset(res.matrix,0,sizeof(res.matrix));
        for(int i=0;i<N;i++)
            res.matrix[i][i]=1;
    }
    Matrix multiplicative(Matrix a,Matrix b)
    {
        Matrix res;
        memset(res.matrix,0,sizeof(res.matrix));
        for(int i = 0 ; i < N ; i++){
            for(int j = 0 ; j < N ; j++){
                for(int k = 0 ; k < N ; k++){
                    res.matrix[i][j] += a.matrix[i][k]*b.matrix[k][j];
                    res.matrix[i][j] %= mod;
                }
            }
        }
        return res;
    }
    Matrix pow(Matrix mx,ll m)
    {
        Matrix res,base=mx;
        init(res);
        while(m)
        {
            if(m&1)
                res=multiplicative(res,base);
            base=multiplicative(base,base);
            m>>=1;
        }
        return res;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n,ant = 0;
            scanf("%lld",&n);
            if(n == 1)  printf("3
    ");
            else if(n == 2) printf("9
    ");
            else
            {
                Matrix res,ans = {
                    0,0,0, 1,0,0, 1,0,0,
                    1,0,0, 0,0,0, 1,0,0,
                    1,0,0, 1,0,0, 1,0,0,
    
                    0,1,0, 0,1,0, 0,0,0,
                    0,1,0, 0,0,0, 0,1,0,
                    0,0,0, 0,1,0, 0,1,0,
    
                    0,0,1, 0,0,1, 0,0,1,
                    0,0,1, 0,0,0, 0,0,1,
                    0,0,1, 0,0,1, 0,0,0
                };
                res=pow(ans,n-2);
    
                for(int i = 0;i < N;i++)
                    for(int j = 0;j < N;j++)
                        ant = (ant + res.matrix[i][j]) % mod;
                printf("%lld
    ",ant);
            }
        }
        return 0;
    }
  • 相关阅读:
    IDEA 2020.1 使用eclipse快捷键
    IDEA 2020.1 配置自定义Maven
    Maven 下载、安装、设置国内镜像
    IDEA 2020.1 下载、安装、激活
    MySQL 5.5/5.7 zip版 下载、安装、卸载、报错
    JDK8 下载、安装、配置环境变量
    如何在虚拟机VM15中安装W10
    虚拟机的安装,VMware-workstation-full-15.5.1-15018445
    为什么要买云服务器
    输入子系统实现的按键驱动
  • 原文地址:https://www.cnblogs.com/lemon-jade/p/9652036.html
Copyright © 2020-2023  润新知