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

智能推荐

git commit提交报错subject may not be empty [subject-empty]-程序员宅基地

文章浏览阅读2.3w次,点赞10次,收藏7次。今天在sourcetree提交写好的代码突然报错,显示如下错误: subject may not be empty [subject-empty] type may not be empty [type-empty]_subject may not be empty

FS102WS是一款用于 LED 灯光开关控制及亮度调节的触摸IC-程序员宅基地

文章浏览阅读187次。每次短按触摸,依OPT1/2/3选择不同,灯光亮度按[高亮度→>中亮度->低亮度->灭]依次循环变化,或[低亮度->中亮度->高亮度->灭]依次循环变化。FS102WS是一款用于 LED 灯光开关控制及亮度调节的触摸IC,支持单通道触摸输入、单路 PWM 输出,可在有介质(如玻璃、亚克力、塑料、陶瓷等)隔离保护的情况下实现触摸功能,可靠性非常高,灯光无闪频。未断电短按开灯后第一次长按调光的方向由之前记忆的亮度值来决定,若记忆亮度值大于45%,则向下调光:若记忆亮度值小于45%,则向上调光。

Python办公自动化实战 09 | Python-docx库:Python与Word的完美结合_ 如何在Word中生成表格?把Python办公自动化进行到底-程序员宅基地

文章浏览阅读911次。本小节主要演示了怎么向Word文档中创建表格并插入数据,并且对表格格式做个性化的设定。_python与word的完美结合

MySQL:从库binlog 使用mysqlbinlog stop-datetime过滤问题-程序员宅基地

文章浏览阅读2k次。更多主从同步相关可以参考我的《深入理解MySQL主从原理》专栏:本文是一个朋友问我问题。从库使用mysqlbinlog..._mysql stop-datetime

SAP入门经验_sap经验-程序员宅基地

文章浏览阅读8k次,点赞18次,收藏30次。SAP入门的经验SAP业务顾问入门确实起点比较高,这在我最开始入门的时候不以为然,但是随着学习的深入,才发现原来老师们说的是真的!简单说一下我自己的入门经历,我是本科是工业工程(IE)专业的,如果有了解的肯定知道这个专业是干什么的,步入这个行业我才发现我所学的专业知识都挺有用的,特别是PP模块,我本身在大学就经常参加一些生产优化案例竞赛,对于排产,MRP等信息有了初步的了解,更重要的是IE专业培养了我的优化意识我感觉这是我的一大笔财富。好了步入正题,说一下我的入门经历:最开始公司培训讲了很多模块的知_sap经验

C++中派生类成员变量和基类成员变量同名问题_c++ 在派生类函数中修改基类同名变量-程序员宅基地

文章浏览阅读8.8k次,点赞5次,收藏18次。1.当派生类存在与基类同名的成员变量时候,派生类的成员会隐藏基类成员,但派生类中存在基类成员的拷贝,要显示的访问BASE::date member#include &lt;iostream&gt;using namespace std;class Base{ public: int a = 10; void print() { cout &..._c++ 在派生类函数中修改基类同名变量

随便推点

【计算机毕设选题】基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉_基于opencv的二维码识别课程设计-程序员宅基地

文章浏览阅读733次,点赞19次,收藏23次。今天学长向大家介绍一个机器视觉的毕设项目,二维码 / 条形码检测与识别基于机器学习的二维码识别检测 - opencv 二维码 识别检测 机器视觉。_基于opencv的二维码识别课程设计

互联网医院智慧医院系统_互联网可访问的医院系统有哪些-程序员宅基地

文章浏览阅读8.5k次。什么是互联网医院?我们来看一下百度百科的定义“互联网医院系统”带有在线问诊、随访、慢病管理等功能,它有实体医院作强有力的支撑,线上方便病人,就是简单的问题不需要到医院,在网上就可以进行。可见在线问诊、随访、慢病管理是互联网医院的核心功能,下面我们来逐个分析一下在线问诊:一般是图文问诊、视频问诊、语音问诊、电话问诊几种问诊方式,多种方式方便医患在线沟通随访:医生可以对患者发起线上随访,患者可在线填写随访表单,后台可统计随访结果慢病管理:能对糖尿病、高血压等常见慢性病进行健康管理,医生可以随时查看病人_互联网可访问的医院系统有哪些

IOS开发 生成app图标_ios app图标生成-程序员宅基地

文章浏览阅读1.6k次。IOS开发,给app设置图标_ios app图标生成

[Python] Django 报错记录与解决_importerror: cannot import name 'iterable' from 'c-程序员宅基地

文章浏览阅读6.7k次,点赞3次,收藏17次。配置记录pycharm中打开Django项目并配置虚拟环境运行项目;将Django项目全局配置文件用统一的包进行管理;配置jinja2模板引擎;补充 Jinja2 模板引擎环境报错记录ImportError;You must set settings.ALLOWED_HOSTS if DEBUG is False;'cryptography' package is required;ImproperlyConfigured_importerror: cannot import name 'iterable' from 'collections

JSON文本互转及JsonNode,ObjectNode,ArrayNode简单理解-程序员宅基地

文章浏览阅读5.7k次。JSON文本互转及JsonNode,ObjectNode,ArrayNode简单理解``JsonNode是Jackson中为了处理JOSN文本的树模型(tree model)。可以将JSON文本转成JsonNode,也可以将JsonNode转成JOSN文本。。ObjectNode和ArrayNode都是JsonNode类的扩展,不同的是JsonNode是只读的,而。..._arraynode

测试理论-程序员宅基地

文章浏览阅读2.6w次,点赞10次,收藏71次。一、基本概念定义:软件测试是为了发现错误而执行程序的过程,“寻找错误”是测试的目的 使用人工或自动手段运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是否弄清预期结果与实际结果之间的差别 软件测试是一种重要的软件质量保证活动,测试过程中的活动包括分析软件和运行软件,是在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软_测试理论

推荐文章

热门文章

相关标签