Deny_小田的博客

小白一只,求神犇轻虐 …

POJ2411 Mondriaan's Dream 【状压dp】

题目链接:http://poj.org/problem?id=2411

题意:
有一个n*m的矩形,有若干个2*1的小长方形,问用小长方形把这个矩形铺满的方案书,多组输入,以 0 0为结束

题解:
在某行中,用一个二进制串来表示铺的情况,0表示当前格子没铺,1表示当前格子铺了,然后YY一下转移,输出dp[n][(2^m)-1],这里的^表示的是幂。
也可以写成:blog上写不出<<啊 QWQ
注意一下位运算的优先级!被坑了!

代码:

#include <cstdio>
#include <cstring>

const int size = (1 << 15) +5;
typedef long long LL;
LL a[15][size];
int n, m;

void init(int d, int s) {
    if(d == m+1) {
        a[1][s] ++;
        return ;
    }

    if( d <= m ) init(d+1, s << 1);
    if( d < m ) init(d+2, s << 2 | 3);
}   

void dfs(int d, int s1, int s2, int t) {
    if(d == m+1) {
        a[t][s1] += a[t-1][s2];
        return ;
    }
    if(d <= m) {
        dfs(d+1, s1 << 1 | 1, s2 << 1, t);
        dfs(d+1, s1 << 1, s2 << 1 | 1, t);
    }
    if(d < m) dfs(d+2, s1 << 2|3, s2 << 2 | 3, t);
}

int swap(int &x, int &y) {
    int t = x; x = y; y = t;
}

int main() {
    while( scanf("%d %d", &n, &m), n+m ) {
        if((n*m)%2) {
            puts("0");
            continue;
        }
        memset(a, 0, sizeof(a));
        if(n > m) swap(n, m);
        init(1, 0);
        for ( int i = 2; i <= n; i ++ ) dfs(1, 0, 0, i);
        printf("%lld\n", a[n][(1<<m)-1]);
    }

    return 0;
}
阅读更多
版权声明:博主小白,如有不当请指出! https://blog.csdn.net/qq_34896694/article/details/66471982
文章标签: poj dp
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭