POJ 2411 Mondriaan's Dream (状压DP)

原题地址:http://poj.org/problem?id=2411

题意:给一个n*m的矩形,你有若干1*2的小矩形,问你有多少种家那个这个矩形填满的方法。

思路:主要参考了大佬的博客;
定义01状态:定义横放的砖块为11,竖放的砖块01
dp状态:定义dp[i][j]表示第i行状态为j的方案数
状态转移:dp[i][j]+= Σ d p [ i 1 ] [ k ] , k
dp初始化:第一行只要连续的1是偶数个就行了,只要满足dp[1][k] (k是某一状态)=1

注意一个long long和位运算的优先级顺序

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    int n, m;
    ll dp[15][2500];
    //dp[i][j]表示第i行状态为j的时候的方案数量

    int init(int s) { //初始化dp数组
            int i = 0;
            while(i < m) {
                if((s & 1 << i) == 0) i++;
                else {
                    if((s & 1 << (i + 1))==0)  return 0;
                    if(i == m - 1) return 0;
                    else i += 2;
                }
            }
        return 1;
    }
    int solve(int x, int y) {
        //判断x是否是合法的
        //判断的时候如果砖头是横着铺的,那么一定是横着的第一块,
        //因为如果是第二块的话,那么一定会在上一次就会被判断
        int i = 0;
        while(i < m) {
            if((x & 1 << i) == 0) {
                if((y & 1 << i)==0) return 0;
                i++;
            } else {
                if((y & 1 << i) == 0) i++;
                else {
                    if(i == m - 1 || (x & 1 << (i + 1)) == 0) return 0;
                    if((y & 1 << (i + 1)) == 0) return 0;
                    i += 2;
                }
            }
        }
        return 1;
    }
    int main() {
        while(~scanf("%d%d", &n, &m), n + m) {
                memset(dp,0,sizeof(dp));
            if(n < m) swap(n, m);
            int sum = (1 << m);
            for(int s=0;s<sum;s++) {
                if(init(s)) dp[1][s]=1;
            }
            for(int i = 2; i <= n; i++) {
                for(int j = 0; j < sum; j++) {
                    for(int k = 0; k < sum; k++) {
                        if(solve(j, k)) dp[i][j] += dp[i - 1][k];
                    }
                }
            }
            printf("%lld\n", dp[n][sum - 1]);
        }
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/81144528