• Jzoj4787 数格子


    题意:用1x2的骨牌填满4xN的格子的方案数

    设f[i][j]表示填到第i行,这一行的状态为j的方案数

    f[i][j]=Σf[i-1][k],其中k->j是一个合法转移

    合法转移要满足两个条件:

    1.若k的第x位为0,那么j的第x位一定要为1 (~k|j==j)

    2.k,j都为一的位置必须是偶数个且必须连续,即k&j的二进制不能出现单独一个1,例如0101不合法,0011和0110都合法

    这样就可以转移了,最后可以用矩阵加速

    #include<stdio.h>
    #include<string.h>
    #define L long long
    const int w[5]={0,3,6,12,15};
    int n,M;
    struct Mat{
    	int n,m;
    	int s[16][16];
    	Mat(){ memset(s,0,sizeof s); }
    	void clr(){ memset(s,0,sizeof s); }
    	void set(int x,int y){ n=x; m=y; }
    	Mat operator * (const Mat& b){
    		Mat c; c.set(n,b.m);
    		for(int i=0;i<n;++i)
    			for(int j=0;j<b.m;++j)
    				for(int k=0;k<m;++k)
    					c.s[i][j]=(c.s[i][j]+(L)s[i][k]*b.s[k][j])%M;
    		return c;
    	}
    } a,b;
    bool ok(int x){
    	for(int i=0;i<5;++i) if(x==w[i]) return 1;
    	return 0;
    }
    void pow(int k){
    	for(;k;b=b*b,k>>=1) if(k&1) a=a*b;
    }
    int main(){
    	a.set(1,16); b.set(16,16);
    	begin:
    	a.clr(); b.clr();
    	for(int i=0;i<16;++i)
    		for(int j=0;j<16;++j)
    			if(((~i&15)|j)==j&&ok(i&j)) b.s[i][j]=1;
    	a.s[0][15]=1;
    	scanf("%d%d",&n,&M);
    	if(n&&M){
    		pow(n);
    		printf("%d
    ",a.s[0][15]);
    		goto begin;
    	}
    }

  • 相关阅读:
    SQL Server事务、视图和索引
    软件系统的分层开发
    OOP应用:实体类
    Oracle/MySql/SQL Sqlserver分页查询
    数据库连接语句
    SQL连接查询
    MySQL基本手册
    C# 其他
    numpy的loadtxt()用法
    Pytorch从一个输入目录中加载所有的PNG图像,并将它们存储在张量中
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7774336.html
Copyright © 2020-2023  润新知