UVA 11270 Tiling Dominoes 初学插头DP

来源:互联网 发布:平面设计软件下载 编辑:程序博客网 时间:2024/04/19 21:12

题意:

有1*2、2*1的两种方块,现有m*n(m*n<101)的地,请问填满方案数。

考虑对于当前状态(i,j)来说dp[now][1/0(放或者不放)][00000000~11111111前m个的状态记为k]

假如上一个状态为 k ,那么现在 应该是 k  << 1  ^ ( 上一个 是否放了 )


如果 k 的第一位是 0 表示 该状态 没放满,即状态无效。


/* *    Author: *        Indestinee *    Date: *        2014.11.16 */ #include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define cls(a) memset(a,0,sizeof(a))#define rise(i,a,b) for(int i=a;i<=b;i++)#define fall(i,a,b) for(int i=a;i>=b;i--)int n, m; ll dp[2][2][1024];int uplimit, now, f;int main(){while( scanf( "%d %d" , &n , &m ) != EOF ){if( n < m ) swap( n , m );if( !m ) {puts( "0" );continue;}f = 1 << ( m - 1 );uplimit = ( 1 << m ) - 1;now = 0;cls( dp[now] );dp[now][1][uplimit] = 1;rise( i , 1 , n )rise( j , 1 , m ){now ^= 1;cls( dp[now] );rise( k , 0 , uplimit ){if( !( k & f ) ) continue; // 状态无效rise( l , 0 , 1 ){//printf( "dp[%d][0][%d] += dp[%d][%d][%d]; = %d \n" , now , ( k << 1 ) ^ l & uplimit , now ^ 1 , l , k , dp[now^1][l][k] );dp[now][0][((k<<1)^l)&uplimit] += dp[now^1][l][k];}if( i > 1 && !((k<<1)&f) ){rise( l , 0 , 1 ){//printf( "dp[%d][1][%d] += dp[%d][%d][%d]; = %d\n" , now , (1<<k)^l^f&uplimit , now ^ 1 , l , k , dp[now^1][l][k]);dp[now][1][((k<<1)^l^f)&uplimit] += dp[now^1][l][k];}}if( j > 1 ){//printf( "dp[%d][1][%d] += dp[%d][0][%d]; = %d\n" , now , ( k << 1 ) ^ 1 & uplimit , now ^ 1 , k ,dp[now^1][0][k] );dp[now][1][((k<<1)^1)&uplimit] += dp[now^1][0][k];}}}cout << dp[now][1][uplimit] << endl;}}

0 0