zoukankan      html  css  js  c++  java
  • TJOI2015 棋盘

    Description

     

    Input

    Output

     

    Sample Input

    2 2
    3 1
    0 1 0
    1 1 1
    0 1 0

    Sample Output

    7
     

    Data Constraint

     

    这题有个巨坑的地方,棋子在第1行,每k列,行和列都是从0开始编号的!!!也就是实际是第2行,第k+1列!!!

    看出来后就一大水题了。

    经过转换可以使得每个棋子都只影响下一行,又由于列只有6,所以用状压解

    f[i][[j]表示每i行状态为j的方案,然后我们发现每2行之间的转移是一样的,所以可以预处理转移矩阵,再矩乘加快速幂优化即可

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<vector>
    using namespace std;
    typedef unsigned int ui;
    
    vector<int> lim[4];
    
    struct Matrix{
        ui a[65][65];
    }pc,d;
    
    ui ans;
    ui f[1011];
    int i,j,k,p,m,nj,l,n,L,sy;
    int a[4][10];
    
    Matrix operator *(Matrix a,Matrix b)
    {
        Matrix c;
        memset(c.a,0,sizeof(c.a));
        int i,j,k;
        for(i=0;i<(1<<m);i++)
            for(k=0;k<(1<<m);k++)if(a.a[i][k]){
                for(j=0;j<(1<<m);j++)c.a[i][j]+=a.a[i][k]*b.a[k][j];
            }
        return c;
    }
    
    Matrix mi(Matrix a,int z)
    {
        Matrix l;
        bool pz;
        int i,j;
        pz=true;
        while(z){
            if(z%2==1){
                if(pz){
                    pz=false;
                    for(i=0;i<(1<<m);i++)
                        for(j=0;j<(1<<m);j++)l.a[i][j]=a.a[i][j];
                }
                else l=l*a;
            }
            a=a*a;
            z/=2;
        }
        return l;
    }
    
    bool check(int ls,int ts)
    {
        int i,j,sy,k;
        for(i=0;i<m;i++)if((ls&(1<<i))){
            for(j=0;j<lim[3].size();j++){
                k=lim[3][j];
                sy=i+1+k-L;
                if(sy>0&&sy<=m){
                    if((ts&(1<<(sy-1))))return false;
                }
            }
        }
        for(i=0;i<m;i++)if((ts&(1<<i))){
            for(j=0;j<lim[2].size();j++){
                k=lim[2][j];
                sy=i+1+k-L;
                if(sy>0&&sy<=m){
                    if(sy!=i+1&&(ts&(1<<(sy-1))))return false;
                }
            }
        }
        return true;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        scanf("%d%d",&p,&L);
        L++;
        for(i=1;i<=3;i++)
            for(j=1;j<=p;j++){
                scanf("%d",&a[i][j]);
                if(a[2][j])lim[2].push_back(j);
                if(a[3][j])lim[3].push_back(j);
            }
        for(i=1;i<=p;i++)if(a[1][i]){
            sy=L+L-i;
            lim[3].push_back(sy);
        }
        for(i=0;i<(1<<m);i++)
            for(j=0;j<(1<<m);j++)if(check(i,j))pc.a[i][j]=1;
        d=mi(pc,n);
        for(i=0;i<(1<<m);i++)if(pc.a[0][i])f[i]++;
        for(i=0;i<(1<<m);i++)ans+=f[i]*d.a[i][0];
        printf("%u
    ",ans);
    }
  • 相关阅读:
    函数
    函数知识点 --- 函数的认知,组成,格式 --------------- #10
    打包app
    vue ie
    css position
    awesome vue
    20110636乐建18588529432
    vue2.0-基于elementui换肤[自定义主题]
    三目运算符,多条件判断
    微信二次开发准备工作
  • 原文地址:https://www.cnblogs.com/applejxt/p/4475539.html
Copyright © 2011-2022 走看看