Mondriaan's Dream 状压dp入门

http://poj.org/problem?id=2411

#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
inline void read(int &x){
    x = 0; int f = 1; char ch = getchar();
    while (!(ch >= '0' && ch <= '9')){if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
    x *= f;
}
int n, m;
LL f[12][1 << 11], tmp;
inline void dfs(int i, int k, int c){
    if (c == m){f[i][k] += tmp; return;}
    //不填充
    dfs(i, k, c + 1);
    //判断能否用1x2的方格填充
    if (c <= m - 2 && !(k & (1 << c)) && !(k & (1 << (c + 1)))) dfs(i, k | (1 << c) | (1 << (c + 1)), c + 2);
}
int main(){
    while (scanf("%d %d", &n, &m), n + m){
        memset(f, 0, sizeof(f));
        tmp = 1;
        dfs(1, 0, 0);//判断第1行用1x2的方格填或不填的方案数
        for (int i = 2; i <= n; i++){
            for (int j = 0; j <= (1 << m) - 1; j++) if (f[i - 1][j]){
                tmp = f[i - 1][j];
                //上一行没有填满的空位都用2x1的方格填满
                dfs(i, ~j & ((1 << m) - 1), 0);
            }
        }
        printf("%lld\n", f[n][(1 << m) - 1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44627639/article/details/88387228