zoukankan      html  css  js  c++  java
  • Blocks_DP&&矩阵快速幂

    参考资料:http://www.tuicool.com/articles/beiyAv

    【题意】有n块砖。现要将砖全部染上红、蓝、绿、黄四种颜色。要求被染成红色和绿色的砖块数量必须为偶数,问一共有多少种染色方案。(由于答案较大,模10007)

    【思路】采用dp,然后转化为矩阵。

    dp:

    用dp[N][4]来表示N块砖块的染色情况,一共有四种状态。

    1.  dp[N][0] :表示N块中红色绿色的数量均为偶数。

    2. dp[N][1] :表示N块中红色为偶数,绿色为奇数。

    3. dp[N][2] :表示N块中红色为奇数,绿色为偶数。

    4. dp[N][3] :表示N块中红色绿色的数量均为奇数。

     而状态转移方程为:

    dp[N+1][0] = 2 * dp[N][0] + 1 * dp[N][1] + 1 * dp[N][2] + 0 * dp[N][3]

    dp[N+1][1] = 1 * dp[N][0] + 2 * dp[N][1] + 0 * dp[N][2] + 1 * dp[N][3]

    dp[N+1][2] = 1 * dp[N][0] + 0 * dp[N][1] + 2 * dp[N][2] + 1 * dp[N][3]

    dp[N+1][3] = 0 * dp[N][0] + 1 * dp[N][1] + 1 * dp[N][2] + 2 * dp[N][3]

    上述的转移方程可以转化为矩阵:

    |2 1 1 0|

    |1 2 0 1|

    |1 0 2 1|

    |0 1 1 2|

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    const int N=5;
    const int mod=10007;
    struct Mat
    {
        int n,m;
        long long int mat[N][N];
        void clear()
        {
            n=m=0;
            memset(mat,0,sizeof(mat));
        }
    };
    Mat mul(Mat a,Mat b)
    {
        Mat c;
        c.clear();
        c.n=a.n;c.m=b.m;
        for(int i=0;i<=a.n;i++)
        {
            for(int k=0;k<=a.n;k++)
            {
                if(a.mat[i][k])
                {
                    for(int j=0;j<=a.n;j++)
                    {
                        c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
                        c.mat[i][j]%=mod;
                    }
                }
            }
        }
        return c;
    }
    Mat pow(Mat a,int k)
    {
        Mat c;
        c.clear();
        c.n=c.m=4;
        for(int i=0;i<4;i++) c.mat[i][i]=1;
        while(k)
        {
            if(k&1) c=mul(c,a);
            k>>=1;
            a=mul(a,a);
        }
        return c;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        Mat a;
        a.clear();
        a.n=a.m=4;
        a.mat[0][0]=2;a.mat[0][1]=1;a.mat[0][2]=1;a.mat[0][3]=0;
        a.mat[1][0]=1;a.mat[1][1]=2;a.mat[1][2]=0;a.mat[1][3]=1;
        a.mat[2][0]=1;a.mat[2][1]=0;a.mat[2][2]=2;a.mat[2][3]=1;
        a.mat[3][0]=0;a.mat[3][1]=1;a.mat[3][2]=1;a.mat[3][3]=2;
        while(t--)
        {
            int n;
            scanf("%d",&n);
            Mat ans=pow(a,n);
            printf("%d
    ",ans.mat[0][0]);
        }
        return 0;
    }
  • 相关阅读:
    查看端口有没有被占用
    微信公众号2()
    How to insert a segment of noise to music file
    puppet practice
    Docker Commands
    LempelZiv algorithm realization
    The algorithm of entropy realization
    Java network programmingguessing game
    Deploy Openstack with RDO and Change VNC console to Spice
    puppet overview
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5976951.html
Copyright © 2011-2022 走看看