UVA11270

题目链接

#include <bits/stdc++.h>


using namespace std;
#define LL long long
const int N = 12;


int n, m, cur;
LL d[2][1<<N];


void update(int a, int b){
    /// 这里检查第一位是否为1是因为如果此处为空,之后的操作再也无法对该位进行填充,这样棋盘就会无法被填满。
    if(b&(1<<m)) d[cur][b^(1<<m)] += d[cur^1][a];
}


int main(){
    while(~scanf("%d%d", &n, &m)){
        if(n < m) swap(n, m);
        memset(d, 0, sizeof d);
        cur = 0;
        int tot = (1<<m) - 1;
        d[0][tot] = 1;///in the begin, value is 1, nothing is placed.
        ///可以这样认为,上面的全部已经铺好,只剩下下面的,要看下面的铺满方式有多少种
        ///也可以这样认为,开始时棋盘为0*0的规格时,铺满棋盘有1种方式,就是什么都不放。
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++){
                cur ^= 1;
                memset(d[cur], 0, sizeof d[cur]);
                for(int k = 0; k <= tot; k++){
                    update(k, k<<1);
                    if(i && !(k&(1<<m-1)))) update(k, (k<<1)^(1<<m)^1);
                    if(j && !(k&1)) update(k, (k<<1)^3);
                }
            }
        printf("%I64d\n", d[cur][tot]);
    }
    return 0;
}
<pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
#define LL long long
#define N 12

int n, m, cur;
LL dp[2][1<<N];

int update(int a, int b){
    if(b&(1<<m)) {
        dp[cur][b^(1<<m)] += dp[cur^1][a];
    }
}

int main(){
    while(~scanf("%d%d", &n, &m)){
        if(n < m) swap(n, m);
        int tot = (1<<m)-1;
        memset(dp, 0, sizeof dp);
        cur = 0;
        dp[cur][tot] = 1;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++){
            cur ^= 1;
            memset(dp[cur], 0, sizeof dp[cur]);
            for(int k = 0; k <= tot; k++){
                update(k, k<<1);
                if(i && !(k&(1<<(m-1)))) update(k, (k<<1)^(1<<m)^1);
                if(j && !(k&1)) update(k, (k<<1)^3);
            }
        }
        printf("%lld\n", dp[cur][tot]);
    }
    return 0;
}


/*
2 10
4 10
8 8
*/


 
 

你可能感兴趣的:(ACM,uva)