zoukankan      html  css  js  c++  java
  • UVA 11270 Tiling Dominoes

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

    题目

    用$1 imes2$骨牌覆盖$n imes m$棋盘,有多少种方法?

    $n imes m<101$

    题解

    棋盘已经填了的部分只能用考虑轮廓线表示清楚,不能只用行和列。轮廓线总共有$2^{宽}$种状态,因此需要把宽度尽量缩小。

    令$nleqslant m$,可以得到$nleqslant 10$,所以轮廓线的状态有$2^{10}$种。

    只在轮廓线的右下角放骨牌,并且保证轮廓线的上面是完全填满了的。比如下图这样的情况

    每次轮廓线都会往右前进一格,那么就需要保证轮廓线第一位在前进后变成1

    规定只允许对轮廓线进行修改,那么就有三种情况

    • 不放
    • 往左放
    • 往上放

    其中不放和往左放都要求第一位是1,往左放还要求最后一位是0且当前位置不是第一列。

    往上放要求第一位是0

    轮廓线的位置有$m imes n$种,状态有$2^{n}$种,其中位置可以滚动优化掉。

    初始状态是$dp[0][(1<<n)-1]=1$,而dp[0]的其他状态因为都含0,导致在后面的某个时刻无法继续转移(第一排,不能往上放,也不能往左或不放),所以虽然会被用到,最后一定会被抛弃。

    ac代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #include<cassert>
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
    using namespace std;
    typedef long long ll;
    int n,m;
    int msk, hi;
    ll dp[2][1<<10];
    int main() {
    	while(~scanf("%d%d", &n, &m)) {
    		if(n>m) swap(n,m);
    		msk = (1<<n)-1, hi=1<<(n-1);
    		dp[0][msk]=1;
    		int now = 0;
    		REP(i,0,m) REP(j,0,n) {
    			now^=1; memset(dp[now],0,sizeof(dp[now]));
    			REPE(k,0,msk) {
    				if(k&1) dp[now][k>>1]+=dp[now^1][k];
    				if(i && !(k&1)) dp[now][(k>>1)|hi]+=dp[now^1][k];
    				if(j && (k&1) && !(k&hi)) dp[now][((k|hi)>>1)|hi]+=dp[now^1][k];
    			}
    		}
    		printf("%lld
    ", dp[now][msk]);
    	}
    }
    
  • 相关阅读:
    arcgis server 中Web墨卡托投影与WGS-84坐标的转换
    jQuery的鼠标事件总结
    Aps.net中基于bootstrapt图片上传插件的应用
    动态添加div及对应的js、css文件
    jQuery时间格式插件-moment.js的使用
    arcgis地图服务之 identify 服务
    ASP.NET导出word实例
    ArcGIS字段计算器分割字段中的字符串
    正则表达式中的特殊字符
    arcgis for js开发之路径分析
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12294908.html
Copyright © 2011-2022 走看看