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

智能推荐

pyspark.linalg模块学习_littlely_ll的博客-程序员秘密

class pyspark.ml.linalg.Vector方法toArray(): 把vector转换为numpy.ndarrayclass pyspark.ml.linalg.DenseVector(ar)v = Vectors.dense([1.0, 2.0])u = Vectors.dense([3.0, 4.0])#可以进行加减乘除v + u #DenseVector([4.0,

Perfect ScrollBar插件使用方法_weixin_30552811的博客-程序员秘密

一、Perfect ScrollBar功能描述 Perfect ScrollBar能够描绘出异乎寻常的页面UI描绘。如果你希望能够设计出与众不同的页面UI设计的话,Perfect ScrollBar可能就是你寻找的解决方案,一个简略可是十分棒的滚动条描绘插件。 Perfect ScrollBar下载 二、Perfect ScrollBar主要...

计算两个时间戳之间相差的日时分秒_huizhang.的博客-程序员秘密

//功能:计算两个时间戳之间相差的日时分秒//$begin_time 开始时间戳//$end_time 结束时间戳function timediff($begin_time,$end_time){ if($begin_time &amp;lt; $end_time){ $starttime = $begin_time; $endtime = $en...

background-size的属性以及ie兼容方法_ZhangRuiJie379的博客-程序员秘密

background-size语法:background-size: length|percentage|cover|contain;值描述测试length设置背景图像的高度和宽度。第一个值设置宽度,第二个值设置高度。如果只设置一个值,则第二个值会被设置为 "auto"。测试perc

cocos2dx 3.10、3.14新建工程在AndroidStudio3.4.2、3.5.2编译通过总结_1024神农氏的博客-程序员秘密

报错:No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android解决:修改local.properties,将NDK改为r9d或r10c版本。将File-&gt;Project Structure下的Android Gradle Plugin Version改为...

指针和句柄的区别_数组句柄指针_ljw5888的博客-程序员秘密

来自http://blog.csdn.net/wenzhou1219总是有新入门的Windows程序员问我Windows的句柄到底是什么,我说你把它看做一种类似指针的标识就行了,但是显然这一答案不能让他们满意,然后我说去问问度娘吧,他们说不行网上的说法太多还难以理解。今天比较闲,我上网查了查,光是百度百科词条“句柄”中就有好几种说法,很多叙述还是错误的,天知道这些误人子弟的人是想干什么。这里我列举...

随便推点

AttributeError: module 'cv2.cv2' has no attribute 'xfeatures2d'_Yahao_Zhang的博客-程序员秘密

是因为opencv的版本问题,将原本安装的opencv卸载,然后重新安装opencv版本3.4.2即可以解决pip install opencv-python3.4.2.16pip install opencv-contrib-python3.4.2.16

C++ zip压缩库使用_c++ zip库_Music 爱好者的博客-程序员秘密

这个压缩库,主要是用来解压和压缩相关文件使用,好处就是引入比较方便,而且极其易使用,方便用户操作。首先是引入这四个文件,相关代码如下:首先是zip.h头文件#ifndef _zip_H#define _zip_H// ZIP functions -- for creating zip files// This file is a repackaged form of the I...

【Docker学习】13、使用 Docker/Docker-Compose 部署 Prometheus 监控组件_Tellsea 小海绵的博客-程序员秘密

文章目录1、Prometheus 监控组件(1)Prometheus 监控 Linux(2)Prometheus 监控 Docker(3)Prometheus 监控 MySQL1、Prometheus 监控组件从上面的构建可以发现,现在已经可以监控当前Linux主机了,实际上能监控的内容很多,可以在官网查看,监控内容或社区查找搭建各种组件的监控,首先需要找到提供数据的数据源,当然,Prometheus已经给我们写好了配置,我们只需要在找到对应的配置进行安装即可,Prometheus GitHub,例如

[latex] latex应用_Eternally123的博客-程序员秘密

git 本地仓库篇创建本地仓库git init//初始化仓库查看仓库状态查看当前分支仓库状态git status``查看历史提交记录git log –pretty=oneline$ git log –pretty=onelineV 3628164fb26d48395383f8f31179f24e0882e1e0 append GPL ea3457...

appserver_Appserver.io乘员组访谈_culh2177的博客-程序员秘密

appserverWhat if you could reliably run PHP without Nginx or Apache, but also without relying on its internal server? What if you could do async operations in PHP with true multi threading, fully taki...

HTTP method 请求方式[email protected]_lislislislislis的博客-程序员秘密

1 GET 请求指定的页面信息,并返回实体主体。2 HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。5 DELETE 请求服务器删除指定的页面。6 C...

推荐文章

热门文章

相关标签