Mondriaan's Dream
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 16771   Accepted: 9683

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

Source

 
第一次做状压题目,没怎么优化就是暴力递推。
对于每个格子我们有这么两种可能: 
第一,这个格子被竖着的砖块覆盖
第二,这个格子被横着的砖块覆盖
我们不妨用0/1来表示这个状态,0表示这是一个竖着放置的砖块的上方部分,1表示横向覆盖或者被上方竖着覆盖。
之所以用0表示竖放的上方是因为竖着放会对下一行的放置造成影响,而横着放显然不会,我们在放置下一行的时候需要知道上一行的状态才可,
所以遇见上一行这个位置是0就表示这个格子已经被覆盖了的状态,利用这个来判断冲突放置。
(显然每个格子都要被覆盖,我们如果用01表示覆盖与非覆盖的状态显然是无意义的,要从放置方式着手,这一点当时想了好久= =)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define LL long long
LL dp[2][2050];
LL ans[15][15];
bool check(int x,int i)
{  return x&(1<<i); }
bool comp(int A,int B,int N)
{
 int i=0,j,k;
 while(i<N){
    if(!check(A,i)){
        if(!check(B,i)) return 0;
        i++;
    }
    else{
        if(!check(B,i)) i++;
        else {
            if(i==N-1||!check(A,i+1)||!(check(A,i+1)&&check(B,i+1))) return 0;
            else i+=2;
        }
    }
 }
 return 1;
}
void solve(int N,int M)
{
 if(ans[N][M]+1) {printf("%lld\n",ans[N][M]);return;}
 memset(dp,0,sizeof(dp));
 dp[0][(1<<N)-1]=1;
 int cur=1;
 for(int i=1;i<=M;++i){
    for(int j=0;j<(1<<N);++j){dp[cur][j]=0;
        for(int k=0;k<(1<<N);++k){
            if(comp(j,k,N)) dp[cur][j]+=dp[cur^1][k];
        }
    }
    cur^=1;
 }
 ans[N][M]=ans[M][N]=dp[cur^1][(1<<N)-1];
 printf("%lld\n",dp[cur^1][(1<<N)-1]);
}
int main()
{
    memset(ans,-1,sizeof(ans));
    int N,M,i,j,k,l;
    while(scanf("%d%d",&N,&M)!=EOF&&(N||M)){
        if(N*M%2==1) {puts("0");continue;}
        if(N>M) {swap(N,M);}
        solve(N,M);  //M行N列
    }
    return 0;
}

POJ 2411 状压DP经典的更多相关文章

  1. POJ 2411 状压dp

    F - Mondriaan's Dream Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I6 ...

  2. POJ 3254 (状压DP) Corn Fields

    基础的状压DP,因为是将状态压缩到一个整数中,所以会涉及到很多比较巧妙的位运算. 我们可以先把输入中每行的01压缩成一个整数. 判断一个状态是否有相邻1: 如果 x & (x << ...

  3. poj 1170状压dp

    题目链接:https://vjudge.net/problem/POJ-1170 题意:输入n,表示有那种物品,接下来n行,每行a,b,c三个变量,a表示物品种类,b是物品数量,c代表物品的单价.接下 ...

  4. [NOI2001] 炮兵阵地 (状压Dp经典例题)

    如果您的电脑比较优秀能在 1sec 内跑过 2^1000 的时间复杂度,不妨你可以尝试一下,其实实际时间复杂度远远少于 2^1000,作为骗分不错的选择QAQ,然后我们来分析一下正解: 很显然此题是一 ...

  5. POJ 3254 状压DP

    题目大意: 一个农民有一片n行m列 的农场   n和m 范围[1,12]  对于每一块土地 ,1代表可以种地,0代表不能种. 因为农夫要种草喂牛,牛吃草不能挨着,所以农夫种菜的每一块都不能有公共边. ...

  6. poj 1185(状压dp)

    题目链接:http://poj.org/problem?id=1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到 ...

  7. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  8. poj 3311 状压DP

    经典TSP变形 学到:1.floyd  O(n^3)处理随意两点的最短路 2.集合的位表示,我会在最后的总结出写出.注意写代码之前一定设计好位的状态.本题中,第0位到第n位分别代表第i个城市,1是已经 ...

  9. 二维状压DP经典题

    炮兵阵地 题目链接 题目大意:在n*m的地图上放置炮兵,每个炮兵的攻击范围是上下左右两格内,有两种不同的地形,山地(用"H" 表示),平原(用"P"表示),只有 ...

随机推荐

  1. tomcat的配置和优化

    tomcat的内存使用配置,最大连接数配置. 如何修改配置呢,在/tomcat的/bin/下面有个脚本文件catailna.sh. 如果 windows 是bat设置tomcat的使用内存,其实就是设 ...

  2. kubernetes实战(八):k8s集群安全机制RBAC

    1.基本概念 RBAC(Role-Based Access Control,基于角色的访问控制)在k8s v1.5中引入,在v1.6版本时升级为Beta版本,并成为kubeadm安装方式下的默认选项, ...

  3. (2.12)Mysql之SQL基础——存储过程条件定义与错误处理

    转自:博客园桦仔 5.存储过程条件定义与错误处理 -- (1)定义 [1]条件定义:declare condition_name condition for condition_value;[2]错误 ...

  4. mysql 数据操作 单表查询 where约束 is null in

    需求找出年龄是 81 或者 73 或者 28 mysql ; +----+-----------+--------+-----+------------+-----------+----------- ...

  5. nodejs中Async详解之一:流程控制

    为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...

  6. [SharpMap] 屏幕坐标和Map坐标转换

    1. SharpMap中屏幕坐标和地图Map坐标转换: using System.Drawing; using GeoAPI.Geometries; namespace SharpMap.Utilit ...

  7. Openstack(十五)快速添加新计算节点

    当后期添加新物理服务器作为计算节点,如果按照上面的过程安装配置的话会非常的慢,但是可以通过复制配置文件的方式快速添加. 15.1计算节点服务安装 #提前将yum仓库.防火墙.selinux.主机名.时 ...

  8. 岭回归&Lasso回归

    转自:https://blog.csdn.net/dang_boy/article/details/78504258 https://www.cnblogs.com/Belter/p/8536939. ...

  9. 【Lua】LDoc生成Lua文档工具的使用

    参考资料: http://my.oschina.net/wangxuanyihaha/blog/188909   LDoc介绍:     LDoc是一个Lua的文档生成工具,过去,比较常用的Lua生成 ...

  10. 解决不能在本地使用JQuery load的方法

    $.ajaxSetup({ xhr: function () { if ("ActiveXObject" in window) { return new ActiveXObject ...