• UVA 11741 Ignore the Blocks


    https://vjudge.net/problem/UVA-11741

    题目

    给一个$n$行$m$列的棋盘,上面有一些坏格子(最多100个),剩下的都是好格子,你有充足的$1 imes2$骨牌,问把所有好格子都不重不漏地覆盖同时不能覆盖坏格子的方法有多少个,$1leqslant nleqslant 4, 1leqslant mleqslant 100000000$,输出对10000007取模后的结果。

    题解

    第一次我直接轮廓线dp到末尾,然后就TLE了……

    因为坏格子比较少,行数也很少,因此把行压成一个状态,计算两行状态之间的转移,得到一个矩阵,然后就可以通过矩阵幂计算了……

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define REP(i,a,b) for(register unsigned i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register unsigned i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(register unsigned i=(a); i>=(b); i--)
    using namespace std;
    typedef long long ll;
    struct node {
    	int a, b;
    	bool operator<(const node&r) const {
    		return b<r.b;
    	}
    };
    #define MAXN 107
    #define MO 10000007
    node bdcol[MAXN];//记录坏格子
    int dp[2][16];//计算转移用的
    int mtx[5][16][16];//转移矩阵
    int ones[5][16][16];//单位矩阵
    inline void db() {
    	memset(ones,0,sizeof(ones));
    	REP(r,1,5) {
    		unsigned msk=1<<r, m=msk>>1;
    		REP(i,0,msk) {
    			ones[r][i][i]=1;
    		}
    		REP(f,0,msk) {
    			memset(dp[0],0,sizeof(dp[0]));
    			dp[0][f]=1;
    			int now=0;
    			REP(i,0,r) {
    				now^=1; memset(dp[now],0,sizeof(dp[now]));
    				REP(k,0,msk) {
    					if(k&1) dp[now][k>>1]+=dp[now^1][k];
    					if(!(k&1)) dp[now][(k>>1)|m]+=dp[now^1][k];
    					if(i && (k&1) && !(k&m)) dp[now][((k|m)>>1)|m]+=dp[now^1][k];
    				}
    			}
    			REP(t,0,msk) {
    				mtx[r][f][t]=dp[now][t];
    			}
    		}
    	}
    }
    int r,c,n;
    unsigned msk, m;
    inline void mul(const int a[16][16], const int b[16][16], int ret[16][16]) { //矩阵乘法
    	int ans[16][16];
    	REP(i,0,msk) {
    		REP(j,0,msk) {
    			ans[i][j]=0;
    			REP(k,0,msk) {
    				ans[i][j]=(ans[i][j]+((ll)a[i][k]*b[k][j]))%MO;
    			}
    		}
    	}
    	memcpy(ret,ans,sizeof(ans));
    }
    inline void qpow(const int a[16][16], int y, int ret[16][16]) { //矩阵幂
    	int ans[16][16];
    	int x[16][16];
    	memcpy(x,a,sizeof(x));
    	memcpy(ans,ones[r],sizeof(ans));
    	for(;y;y>>=1) {
    		if(y&1) mul(ans,x,ans);
    		mul(x,x,x);
    	}
    	memcpy(ret,ans,sizeof(ans));
    }
    int A[16][16];
    int B[16][16];
    int main() {
    	int kase=1;
    	db();
    	while(~scanf("%d%d%d", &r, &c, &n) && r) {
    		msk = 1u<<r; m=msk>>1;
    		REP(i,0,n) {
    			scanf("%d%d", &bdcol[i].a, &bdcol[i].b);
    		}
    		REP(i,0,r) {
    			bdcol[n].a=i, bdcol[n].b=c;
    			n++;
    		}
    		sort(bdcol,bdcol+n);
    		int now=0, from=-1;//当前坏格子编号和列
    		memcpy(A,ones[r],sizeof(A));
    		int i=0;
    		while(i<n) {
    			now=i;
    			unsigned k=0;
    			while(i<n && bdcol[i].b==bdcol[now].b) {k|=1<<bdcol[i].a; i++;}
    			qpow(mtx[r], bdcol[now].b-from, B); //B=F^{...}
    			mul(A,B,A);
    			memset(B,0,sizeof(B));
    			REP(i,0,msk) REP(j,0,msk) if(!(j&k)) {
    				B[i][j|k]+=A[i][j];
    			}
    			memcpy(A,B,sizeof(A));
    			from = bdcol[now].b;
    		}
    		
    		printf("Case %d: %d
    ", kase, A[msk-1][msk-1]);//从-1排满到最后一排满
    		kase++;
    	}
    	return 0;
    }
    
  • 相关阅读:
    在阿里云服务器上安装MySQL
    mui中调用ajax时报abort错误
    IDEA根据数据库表生成pojo对象
    java.io.IOException: All specified directories have failed to load.
    mysql隔离级别
    java8新特性
    数据库语言分类
    Spring AOP 代码示例
    java NIO学习(二)
    java NIO学习(一)
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12328067.html
Copyright © 2020-2023  润新知