POJ 2411 Mondriaan's Dream (状压DP)

原创 2015年07月07日 18:36:22

题意:用宽为2,高为1的小矩形,拼成一个h*w的大矩形,问有多少种拼法。

开始想的时候,从下往上不断铺,考虑每一行的铺的方式,对于每一行的第i个格,如果被横放的矩形覆盖的话,状态为1,如果被竖放的矩形覆盖的话,状态为0。想了一种状态转移,但是复杂度太大了。然后想到最后结果是最后一行全铺满的情况。。如果不铺满又怎样。。那么让每一行的第i个格,如果被覆盖就为1,不被覆盖就为0,然后方程就出来了。


思路:状态表示如上述。设dp[i][S] 为第i行状态为S,前i-1行全铺满的方式数。

考虑第i行和第i-1行的关系:如果第i行第j个格为0,那么第i-1行第j个格必须是1;如果第i行第j个格为1,第i-1行第j个格可以是1也可是0,因为如果第i行第j个格是被竖放的矩形覆盖的话,那么其下为0,反之为1 。但因为每一行横放矩形占有两个格,所以第i行每一段1下面必须有偶数或0个1。

状态转移方程:dp[i][S] += dp[i-1][S'] (S'满足上述关系)


我的代码:

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;
typedef __int64 LL;
const LL maxn = 12;

LL dp[maxn][1<<maxn];
int h,w;

bool check(int s,int t){
    if(((s | t) + 1) >> w != 1) return false;
    int tmp = s & t,cnt = 0;
    while(tmp){
        if(tmp & 1) cnt++;
        else{
            if(cnt % 2 == 1) return false;
            cnt = 0;
        }
        tmp >>= 1;
    }
    if(cnt % 2 == 1) return false;
    return true;
}

void solve(){
    int Ed = 1 << w;
    for(int j = 0 ;j < Ed; j++){
        if(check(j,Ed - 1)) dp[0][j] = 1;
        //cout<<dp[0][j]<<" ";
    }
    //cout<<endl;
    for(int i=1;i<h;i++){
        for(int j=0;j<Ed;j++){
            for(int k=0;k<Ed;k++){
                if(check(j,k)) {
                    dp[i][j] += dp[i-1][k];
                    //cout<<j<<" and "<<k<<endl;
                }
            }
            //cout<<dp[i][j]<<" ";
        }
        //cout<<endl;
    }
    printf("%I64d\n",dp[h-1][Ed-1]);
}

int main(){
    while(~scanf("%d%d",&h,&w)){
        if(h + w == 0) break;
        if(h < w) swap(h,w);
        memset(dp,0,sizeof(dp));
        solve();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

poj2411 Mondriaan's Dream--状压dp

原题链接:http://poj.org/problem?id=2411 . 题意:一个n*m的方格,给定一个1*2的方块,要求用这个方块填充方格,填满,一共多少种填充方法。 分析:对于一...
  • LaoJiu_
  • LaoJiu_
  • 2016年10月26日 13:22
  • 263

poj 2411 Mondriaan's Dream 经典状压DP+记忆化搜索

转送门:poj 2411 Mondriaan’s Dream题目大意给出一个n*m的棋盘,及一个小的矩形1*2,问用这个小的矩形将这个大的棋盘覆盖有多少种方法。解题思路因为对应于一个方格来讲,有两种状...

Mondriaan's Dream POJ - 2411 状压DP

用2进制的01表示不放还是放 第i行只和i-1行有关 枚举i-1行的每个状态,推出由此状态能达到的i行状态 如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的...

POJ2411 Mondriaan's Dream 【状压dp】

题目链接:http://poj.org/problem?id=2411题意: 有一个n*m的矩形,有若干个2*1的小长方形,问用小长方形把这个矩形铺满的方案书,多组输入,以 0 0为结束题解: 在...

poj2411 Mondriaan's Dream(状压dp)

Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producin...

POJ 2411 Mondriaan's Dream [状压DP做法]

状压DP(多米诺骨牌问题)

POJ 2411-Mondriaan's Dream(状压DP->骨牌铺满问题)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226...

poj 2411 Mondriaan's Dream(状压DP->求铺方格的方法数)@

Mondriaan's Dream Time Limit:10000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Subm...

POJ 2411 Mondriaan's Dream 状压dp

题目大意:给定n*m的方格图,求用1*2的砖块铺满的方案总数。 题目分析:对于i行j列的格子,有三种情况:1.不填,被i-1行j列的填了。2.填,和i行j-1列构成一个砖块。3.填,同时填上i+1...

poj2411Mondriaan's Dream【覆盖类状压dp】

Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, a...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2411 Mondriaan's Dream (状压DP)
举报原因:
原因补充:

(最多只允许输入30个字)