poj2411 Mondriaan's Dream (轮廓线dp、状压dp)_weixin_30780221的博客-程序员秘密

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

智能推荐

数据归一化的基本方法_归一化计算公式的参数_Lucky_girlhh的博客-程序员秘密

1.线性归一化简单公式表达:y = (x-min Value)/(max Value-min Value)其中,x是归一化之前的数据,y是归一化之后的数据,max Value 和 min Value 分别对应这一组数据中的最大值和最小值。范围:[0,1]。适用于:把原来数据等比例缩放限定在某一范围内,在不涉及距离度量和协方差计算的时候使用。2.标准差归一化简单公式表达:y = (x-...

BufferedReader剖析_weixin_34220963的博客-程序员秘密

2019独角兽企业重金招聘Python工程师标准&gt;&gt;&gt; ...

二维高斯分布(Two-dimensional Gaussian distribution)_<Running Snail>的博客-程序员秘密

1、多维高斯分布的概率密度函数多维变量X=(x1,x2,...xn)X=(x_1,x_2,...x_n)X=(x1​,x2​,...xn​)的联合概率密度函数为:       其中:  d:变量维度。对于二维高斯分布,有d=2;  u=(u1u2…un)u=(u_1 u_2 … u_n)u=(u1​u2​…un​):各位变量的均值;  Σ:协方差矩阵,描述各维变量之间的相关度。对于二维高斯分布,有:后文主要分析均值和协方差矩阵对二维高斯分布的影响。2、均值和协方差矩阵对二维高斯分布的影响

《程序员》2005年4月文章——陈榕访谈_陈榕 程序员杂志_myan的博客-程序员秘密

软件正迈向“空”的境界——陈榕访谈 编者按:科泰世纪公司CEO陈榕,是软件技术圈子里的知名人士。他长期在微软公司从事Windows核心部分的开发,在操作系统和软件开发模型上有着独特的技术间接。回国创业之后,陈榕一方面致力于国产嵌入式操作系统的研发,另一方面也不遗余力地将先进的软件技术理念和工程方法引入国内。当网上围绕3G的争论如火如荼的时候,本刊记者在清华园中采访了陈榕,本来是想听听他对3G的看法

Android开发 - 收藏集_android开发 商品收藏夹_产品人的世界的博客-程序员秘密

Android 自定义View的各种姿势1Activity的显示之ViewRootImpl详解Activity的显示之ViewRootImpl初探Activity的显示之Window和ViewAndroid系统的创世之初以及Activity的生命周期图解Android事件分发机制(深入底层源码)Android 自定义View的各种姿势2Android 内存泄漏分析与解决Android消息机制Android Binder(也许是最容易理解的)Android 彻底掌握Bi

数据库5之完整性约束的实现_哪种方式可以实现数据约束_香菜小姐的博客-程序员秘密

在上一篇文章中,我们已经对完整性约束有了一定的概念,并且做了分类。实验操作放在另外一篇文章分类:1.实体完整性约束2.域完整性约束3.那么怎么实现完整性约束呢?1.完整性规则的定义:通过SQL,也可以SSMS交互式创建2.(运行时)进行完整性规则的检查一、实体完整性约束1.主码(primary key)约束--&amp;gt;可以定义为表级约束条件,也可以定义为列级约束条件区别:2.唯一(unique)约...

随便推点

思科第四学期章节练习_weixin_33716154的博客-程序员秘密

这是我自己总结的98%的正确率 转载于:https://blog.51cto.com/likai/216196

第六届GPLT团体程序设计天梯赛_翼轸 的博客-程序员秘密

文章目录前言一、L11、人与神 (5 分)2、两小时学完C语言 (5 分)3、强迫症 (10 分)4、降价提醒机器人 (10 分)5、大笨钟的心情 (15 分)6、吉老师的回归 (15 分)二、使用步骤1.引入库2.读入数据总结欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公.

事务消息中心-TMC_信息系统事务中心_jessicaiu的博客-程序员秘密

此文已由作者杨凯明授权网易云社区发布。欢迎访问网易云社区,了解更多网易技术产品运营经验。背景为什么要做事务消息中心原有kqueue的方式缺点:降低业务库性能占用业务库磁盘历史数据管理成本高技术运维工作量很大事务消息中心的优点:去除上述kqueue的缺点易运维易扩展事务消息中心的缺点:接入适当改造增加网络开销TMC基本概念事务消息中心主要是提供两阶段提交的方案,对业务方消息提供保证投递的支持。支持R...

IDA动态调试apk、AndroidStudio调试apk,包括Service组件_Dr. 熊的博客-程序员秘密

IDA调试APK的activity1、连接上模拟器adb connect 127.0.0.1:62001(夜神模拟器)2、配置IDA的属性Debugger-&amp;gt;Debugger Options表示遇见进程、线程、库文件的出入口会被挂起2018-10-24_173515.png选择好adb工具具体路径,填好包名、活动名...

一个使用gurobi过程中让人忍俊不禁的问题_gurobi gap_九手算法工程师的博客-程序员秘密

@[TOC]一个使用gurobi过程中让人忍俊不禁的问题关于gurobi输入数据过大导致不能使用的问题在知乎上看到03年美国数学建模竞赛的B题 有一个较好的答案,程序也很完整准备试着跑一下代码。链接: link.看到需要安装gurobi 就按照链接: link进行了安装,代码调试也正确。但是输入数据只有101010的三维数据,然后就自行将数据改为505050结果程序就不跑了 ,我还以为是我的licenses过期了,找了半天看怎么解决过期问题,看到如果不是在校生或者付费的话 没有办法解决。在绝望的

在本地用 Navicat 连接远程数据库报错:Can't connect to MySQL server on 。。。_Anlior的博客-程序员秘密

在腾讯云新买了一台服务器,环境都安装好了,在本地用 Navicat 连接数据库,就是连接不上,一直报错Can’t connect to MySQL server on 。。。搞了三四个小时,终于搞定,分享一下过程。一、检查用户授权 1.进入ubuntu mysql命令界面,查看root用户授权show grants for 'root'@'%'; 2.如果没有授权记录,新增用户CREATE USE

推荐文章

热门文章

相关标签