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

计蒜客 https://nanti.jisuanke.com/t/31721

题意:有肉,鱼,巧克力三种食物,有几种禁忌,对于连续的三个食物,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\n");
        else if(n == 2) printf("9\n");
        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\n",ant);
        }
    }
    return 0;
}

 

posted @ 2018-09-15 20:15  jadelemon  阅读(662)  评论(0编辑  收藏  举报