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

原创 2016年08月02日 01:14:47

转送门:poj 2411 Mondriaan’s Dream

题目大意

给出一个n*m的棋盘,及一个小的矩形1*2,问用这个小的矩形将这个大的棋盘覆盖有多少种方法。

解题思路

因为对应于一个方格来讲,有两种状态放或者不放
对应于一个1*2的矩形来说有三种方式:横着放,竖着放,不放
因为列的数量为指数级别的,行为线性的,所以我们选取大的最为行,小的作为列
所有dp[i][j]就表示第i行状态为j的时候方法数
那么很明显dp[i][nowsta] = {dp[i-1][presta]}
对于每种2*1的矩形我们有下面的三种方式
1 横放

如果第i行第d列我们选择横放,那么第i行的第d列及d+1列都是1了,第i-1行第d列及d+1列也都必须为1(保证是满的),及状态转移为:

d=d+2,curstate=curstate<<2|3,prestate=prestate<<2|3.

2竖放

第i行第d列我们选择竖放,那么第i行第d列为1,第i-1行d列必须是0,(因为我们是竖着放的,如果前一行不是空的如何能放下呢),状态转移:

d=d+1,curstate=curstate<<1|1,prestate=prestate<<1.

3不放

第i行第d列不妨,那么第i-1行d列肯定是1,(保证是满的),状态转移:

d=d+1,curstate=curstate<<1,prestate=prestate<<1|1.

这个题目采用记忆化搜索,对已经计算出的状态值方法记录,还有就是初始化的时候将dp[0][2<

AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 12;
long long dp[MAXN][1<<MAXN];
int col,row;
void dfs(int r,int c,int preSta,int nowSta)
{
    if(c == col)
    {
        dp[r][nowSta]+=dp[r-1][preSta];
        return ;
    }
    if(c+1<=col)
    {
        dfs(r,c+1,preSta<<1,nowSta<<1|1);
        dfs(r,c+1,preSta<<1|1,nowSta<<1);
    }
    if(c+2<=col)
        dfs(r,c+2,preSta<<2|3,nowSta<<2|3);
}
int main()
{

    while(~scanf("%d%d",&col,&row) && row&&col)
    {
        if((col*row)%2)
        {
            printf("0\n");
            continue;
        }
        if(col>row) swap(col,row);
        memset(dp,0,sizeof dp);
        dp[0][(1<<col)-1] = 1;
        for(int i=1;i<=row;i++) dfs(i,0,0,0);
        printf("%lld\n",dp[row][(1<<col)-1]);
    }
    return 0;
}
版权声明:本文为博主原创文章,转载请注明出处

相关文章推荐

POJ 2411 && HDU 1400 Mondriaan's Dream (状压dp 经典题)

POJ 2411 && HDU 1400 Mondriaan's Dream (状压dp 经典题)

poj2411 Mondriaan's Dream--状压dp

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

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个字)