poj2411 Mondriaan's Dream (轮廓线dp、状压dp)-程序员宅基地

Mondriaan's Dream

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 17203   Accepted: 9918

Description

Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series' (where he had to use his toilet paper to draw on, for all of his paper was filled with squares and rectangles), he dreamt of filling a large rectangle with small rectangles of width 2 and height 1 in varying ways. 

Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!

Input

The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, 1<=h,w<=11.

Output

For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.

Sample Input

1 2
1 3
1 4
2 2
2 3
2 4
2 11
4 11
0 0

Sample Output

1
0
1
2
3
5
144
51205

题意:

用 1 x 2 的矩形骨牌覆盖 h x w 的矩形,问有多少种不同的覆盖方法。

思路:

轮廓线dp(状压dp),以一个 w(矩形的宽) 位的二进制数(设为 k)表示一个状态,对应位上的 0 表示未覆盖的状态、1 表示已覆盖。

我们以从左到右、从上倒下的顺序做决策,要决策的点是 k 所表示的状态的下一个位置,以此点作为骨牌的右下角,

即:若我们在当前点竖着放置一块骨牌,它将覆盖当前点和正上方一点;若我们横着放置一块骨牌,它将覆盖当前点和左边的点。只有这样决策,才保证了是从之前的状态转移过来。

且以上述方式记录状态,k 的最高位正好是决策点的正上方一点,最低位是决策点的左边一点,并且我们每次决策都要保证最高位为 1 ,否则在以后的决策中都无法为其覆盖骨牌,也就无法达到全覆盖的要求。

这样,对于每个点都有三种决策方式:

  1. 放一块竖着的骨牌,要满足的条件有:k 的最高位不为 1 ;当前点不在第一行。则转移后的状态是 curk = k<<1|1,左移一位并将最低位覆盖;
  2. 放一块横着的骨牌,要满足的条件有:k 的最高位是1、最低位不试 1;当前点不在第一列。转移后的状态是 curk=(k|1)<<1|1,在覆盖最低位,左移一位后再覆盖最低位;
  3. 不妨骨牌,要满足的条件有: k 的最高位是 1;状态 curk = k<<1;

注:每次状态转移后都要清除高于 w 位的多余位,这些并不是状态的一部分;左移得到下一状态应该好理解。

代码:

#include<iostream>
#include<bitset>
#include<cstring>
using namespace std;
const long long maxn = 12, INF = 0x3f3f3f3f;

long long dp[2][1<<maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long h, w;
    while(cin>>h>>w && (h+w))
    {
        memset(dp, 0, sizeof(dp));
        long long cur=0, curk;
        dp[cur][(1<<w)-1]=1;
        for(int i=0; i<h; ++i)
        {
            for(int j=0; j<w; ++j)
            {
                cur=1-cur;
                memset(dp[cur], 0, sizeof(dp[cur]));
                for(int k=0; k<(1<<w); ++k)
                {
                    if(i>0 && !(k&(1<<(w-1))))//放一块竖着的骨牌,覆盖当前位置和正上方的位置
                    {
                        curk=k<<1|1;
                        curk=curk&((1<<w)-1);//清除多余的位
                        dp[cur][curk]+=dp[1-cur][k];
                    }
                    if(j>0 && !(k&1) && (k&(1<<(w-1))))//放一块横着的骨牌,覆盖当前位置和左边的位置
                    {
                        curk=(k|1)<<1|1;
                        curk=curk&((1<<w)-1);
                        dp[cur][curk]+=dp[1-cur][k];
                    }
                    if((k&(1<<(w-1))))//不放
                    {
                        curk=k<<1;
                        curk=curk&((1<<w)-1);
                        dp[cur][curk]+=dp[1-cur][k];
                    }
                }
            }
        }
        cout<<dp[cur][(1<<w)-1]<<endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/xiepingfu/p/7289572.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30780221/article/details/99804200

智能推荐

KITTI数据集介绍_kitti数据集相机的基线长度-程序员宅基地

文章浏览阅读1.8k次。数据采集平台: 1个彩色摄像头立体声对, 1个灰度摄像头立体声对, 1个64线激光雷达, 1个GPS/IMU先上采集装置实物图:坐标系统的定义如下, 其中方向以司机看向前方道路的视角给出.Camera: x: right, y: down, z: forwardVelodyne: x: forward, y:..._kitti数据集相机的基线长度

Pytorch显示一个Tensor类型的图片数据_pytorch image tensor 如何显示-程序员宅基地

文章浏览阅读7.3k次,点赞6次,收藏9次。Pytorch显示一个Tensor类型的图片数据import torchfrom torchvision.transforms import ToPILImageshow = ToPILImage() # 可以把Tensor转成Image,方便可视化pic=torch.randn(3, 500, 500)ToPILImage()(pic).show()显示效果_pytorch image tensor 如何显示

一款非常优秀的内存数据库——lmdb-程序员宅基地

文章浏览阅读8k次,点赞4次,收藏30次。lmdb是一款开源的高效快速的内存映射数据库,C语言编写,基于B+树索引,支持MVCC事务处理,是一个嵌入到进程的数据库,不需要单独的数据库进程,在代码中使用lmdb的接口即可方便地实现读写lmdb数据库。github:https://github.com/LMDB/lmdb.git下载并编译、安装git clone https://github.com/LMDB/lmdb.gitcd lmdb/libraries/liblmdbmakesudo make install示例代._lmdb

upstream prematurely closed connection while reading response header from upstre-程序员宅基地

文章浏览阅读6.2k次。[code="java"]请求对方用nginx做了代理:但是error.log报upstream prematurely closed connection while reading response header from upstream, client找了半天,host没set进去[/code]原来配置[code="java"]location / { ..._apache upstream prematurely closed connection while reading upstream

hadoop(三) - HDFS分布式存储系统_java 50060 端口-程序员宅基地

文章浏览阅读2.6k次。一. 分布文件系统和HDFS:其实我们可以把分布式文件系统HDFS理解为windows文件系统, 可以在文件夹里面分门别类地存放文件, 只不过HDFS通过网络把文件存放在多台主机上二. HDFS的shell操作:HDFS是存取数据的分布式文件系统, 对HDFS的操作就是文件系统的基本操作, 比如文件的创建、修改、删除、修改权限等对HDFS的操作命令类似Linux的shell对文件的操作, 如: ls、mkdir、rm等HDFS命令选项:1. - ls 显示当前目录结构_java 50060 端口

数据库的四种语言_数据库的所有语言-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。1. 数据查询语言DQL数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE子句组成的查询块:SELECT <字段名表>FROM <表或视图名>WHERE <查询条件>2 .数据操纵语言DML数据操纵语言DML主要有三种形式..._数据库的所有语言

随便推点

传统算法 - 霍夫圆检测原理-程序员宅基地

文章浏览阅读5.7k次。以下转载自 https://blog.csdn.net/dcrmg/article/details/52506538霍夫圆变换的基本思路是认为图像上每一个非零像素点都有可能是一个潜在的圆上的一点,跟霍夫线变换一样,也是通过投票,生成累积坐标平面,设置一个累积权重来定位圆。在笛卡尔坐标系中圆的方程为:其中(a,b)是圆心,r是半径,也可以表述为:即所以在abr组成的三维坐标系中,一个..._霍夫圆检测原理

QT中出现main.error错误的解决方法,_qtbase/src/tools/syncqt/main.cpp:25:10: fatal erro-程序员宅基地

文章浏览阅读2.8k次。问题:最近在虚拟机的Linux上安装QT,编译一个在其它地方没有问题的程序的时候出现了main.error的问题,捣鼓了好久,现在终于是能够用了,现将解决过程记录如下,如果有遇到相同问题的朋友不妨可以试试看解决方法:在网上查了一些资料,说的都可能是GCC的问题我的系统上的GCC有两个版本,系统自带的4.4.2是装在目录/usr/bin下,而我新装的支持C++11的版_qtbase/src/tools/syncqt/main.cpp:25:10: fatal erro

Java基础之IO_javasio-程序员宅基地

文章浏览阅读130次。Java I/O流是一组有顺序的,有起点和终点的字节集合。是对设备文件间数据传输的总称和抽象。在IO中涉及的设备文件包括文件、控制台、网络链接等,这其中又根据流的方向可以将两端的设备文件分为数据源对象和接收端对象数据源对象:有能力产出数据 接收端对象:有能力接收数据而IO流实际上屏蔽了在实际设备中的处理数据的细节,这些处理方式也叫通信方式可以包括顺序、随机存取、缓冲、二进制、按..._javasio

springcloud父子工程的构建和组件的使用-----springcloud全课程总结_spring cloud父项目的明明规则-程序员宅基地

文章浏览阅读1.2k次。1.新建父工程下一步是可选择的用quickstart,但是实际用的是下面的这种方式创建的。 开始这个一定要选pom工程。粘贴pom的文件: gav坐标注意这个坐标是十分重要的。 常用的pom总结: ..._spring cloud父项目的明明规则

c++ auto tuple decltype std::bind_auto tuple-程序员宅基地

文章浏览阅读1.6k次。tuple(元组)。tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多细节,要揭开它神秘的面纱时又比较困难。  tuple是一个固定大小的不同类型值的集合,是泛化的std::pair。和c#中的tuple类似,但是比c#中的tuple强大得多。我们也可以把他当做一个通用的结构体来用,不需要创建结构_auto tuple

微信企业号 获取用户信息_企业微信 通过open id 获取用户信息-程序员宅基地

文章浏览阅读3.5k次,点赞2次,收藏5次。企业号的网页开发,说白了就是移动端web开发,特殊点在于如何获取微信用户的身份信息。在企业号中可以进行如下步骤获取微信用户信息:访问一个业务页面时,可通过OAuth验证接口获取此用户信息 → 根据code获取userId → 根据userId获取微信信息。① 获取codeAPI:http://qydev.weixin.qq.com/wiki/index._企业微信 通过open id 获取用户信息

推荐文章

热门文章

相关标签