POJ 2411 Mondriaan's Dream (状压DP)

本文介绍了一种使用1*2矩形拼接任意h*w矩形的方法,通过递推动态规划解决拼接方案计数问题。利用位运算记录每行的状态,并确保相邻行的砖块布局合法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:用1*2的矩形拼成和h*w的矩形有几种拼法.(h, w <= 11)


思路:用1表示该处竖着放一块砖,用0表示横着放的砖,或者竖着放的第二行。显然同一列上下两行不能同时为1,

一行中每个未放竖的矩形区间中的0量一定要是2的倍数。这样从第一行递推到第h行,最后答案是dp[h][0],因为前

i-1行状态确定最后一行的状态也就定。



代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 12;
ll dp[maxn][1<<maxn];
int h, w;

bool judge(int x)
{
    int cnt = 0;
    for(int i = 0; i < w; i++)
    {
        if(x%2)
        {
            if(cnt%2) return 0; //一行中区间未标记的数量一定要是2的倍数
        }
        else cnt++;
        x /= 2;
    }
    if(cnt%2) return 0;
    else return 1;
}

int main(void)
{
    while(cin >> h >> w)
    {
        if(!h && !w) break;
        if(w*h%2) { puts("0"); continue; }
        if(w > h) swap(w, h);
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        int tot = 1<<w;
        for(int i = 1; i <= h; i++)
            for(int j = 0; j < tot; j++)
                for(int k = 0; k < tot; k++)
                    if(!(j&k)&&judge(j^k))  //j^k上一行的列铺了竖着的,这一行这列标记1
                        dp[i][j] += dp[i-1][k];
        printf("%lld\n", dp[h][0]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值