题目链接:http://poj.org/problem?id=2411


解题心得:

  1. 可以说是很经典的一个状压dp了,写dfs遍历肯定是要超时的,这个题的状态转移方程对新手来说有点吃力。
  2. 状态转移用的是上凸法,就是如果一行中(除了最后一行)有一个是空位,那么必定是下面一行竖着摆放的矩形,这样才符合条件。这样就把两行中的状态联系起来了,枚举每两行的状态来进行检验,还可以进行状态的累加。
  3. 这个题还有一些小技巧,
    • 如果列数大于行数可以将列和行互换,因为在计算行和列的复杂度是完全不同的,列是o(2^n),行是o(n)。,
    • 另一个就是因为行列数量级很小,测试样例可能很多,可以把每次的答案记录下来,这样在有答案的时候可以直接输出。
    • -


#include<stdio.h>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = (1<<11)+10;
long long dp[15][maxn],ans[15][15];
int n,m,Max; bool init(int x)
{
int i=0;
while(i<m)
{
if(x&(1<<i))
{
if(i == m-1)//不能超出边界
return false;
if(x&(1<<(i+1)))//一个横放的矩形
i += 2;
else
return false;
}
else
i++;
}
return true;
} bool ok(int x,int y)
{
int i = 0;
while(i<m)
{
if(x&(1<<i))//两个都是横放的
{
if(y&(1<<i))
{
if(i == m-1 || !(x&(1<<(i+1))) || !(y&(1<<(i+1))))
return false;
else
i+=2;
}
else
i++;
}
else//当前行有放置的矩形,上一行是空
{
if(y&(1<<i))
i++;
else
return false;
}
}
return true;
} void solve()
{
Max = (1<<m) -1;
memset(dp,0,sizeof(dp));
for(int i=0;i<=Max;i++)//特殊的第一行初始化
{
if(init(i))
dp[0][i] = 1;
}
for(int i=1;i<n;i++)
for(int s=0;s<=Max;s++)//枚举每两行符合条件的放置方式
for(int ss=0;ss<=Max;ss++)
{
if(ok(s,ss))
dp[i][s] += dp[i-1][ss];
}
printf("%lld\n",ans[n][m] = ans[m][n] = dp[n-1][Max]);
} int main()
{
memset(ans,0,sizeof(ans));
while(cin>>n>>m)
{
if(m > n)//如果行小于列,直接交换行和列
swap(n,m);
if(n+m == 0)
break;
if(ans[n][m] || ans[m][n])//记录已经出现过的答案
{
printf("%lld\n",ans[n][m]);
continue;
}
if((n*m)%2 == 1)//如果行列都是奇数那么没有符合条件的方案
{
printf("0\n");
continue;
}
solve();
}
}

POJ:2411-Mondriaan's Dream(矩形拼接方案)的更多相关文章

  1. POJ 2411 Mondriaan's Dream 插头dp

    题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...

  2. Poj 2411 Mondriaan's Dream(压缩矩阵DP)

    一.Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, ...

  3. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  4. POJ - 2411 Mondriaan's Dream(轮廓线dp)

    Mondriaan's Dream Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nig ...

  5. [POJ] 2411 Mondriaan's Dream

    Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18903 Accepted: 10779 D ...

  6. Poj 2411 Mondriaan's Dream(状压DP)

    Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Description Squares and rectangles fascina ...

  7. [poj 2411]Mondriaan's Dream (状压dp)

    Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18903 Accepted: 10779 D ...

  8. POJ 2411 Mondriaan's Dream/[二进制状压DP]

    题目链接[http://poj.org/problem?id=2411] 题意:给出一个h*w的矩形1<=h,w<=11.用1*2和2*1的小矩形去填满这个h*w的矩形,问有多少种方法? ...

  9. poj 2411 Mondriaan's Dream(状态压缩dp)

    Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, af ...

  10. poj 2411 Mondriaan's Dream 轮廓线dp

    题目链接: http://poj.org/problem?id=2411 题目意思: 给一个n*m的矩形区域,将1*2和2*1的小矩形填满方格,问一共有多少种填法. 解题思路: 用轮廓线可以过. 对每 ...

随机推荐

  1. SpringMVC简介01

    SpringMVC也叫Spring Web mvc,属于表现层的框架.SpringMVC是Spring框架的一部分,是在Spring3.0后发布的. Spring结构图: SpringMVC架构: S ...

  2. dubbo rest返回值异常Incompatible types: declared root type

    2018-08-28 17:26:02,208 [http-bio-9090-exec-1][][][][][] ERROR com.wjs.member.plugin.intercepter.Ser ...

  3. 洛谷CF784E Twisted Circuit

    (本题本来可能也就普及难度但是硬生生给评成了一道NOI难度的紫题,有点无语...) 这道题目是一道愚人节题目,本来只有下面的电路图,结果翻译完之后难度就直接没了. ------------ 言归正传, ...

  4. ZR#331. 【18 提高 3】括号序列(栈)

    题意 挺神仙的.首先$60$分暴力是比较好打的. 就是枚举左端点,看右端点能否是$0$ 但是这样肯定是过不了的,假如我们只枚举一次,把得到的栈记录下来 那么若区间$(l, r)$是可行的,那么$s_{ ...

  5. Author: Jan Odvarko, www.janodvarko.cz

    /*  * Author: Jan Odvarko, www.janodvarko.cz */ FBL.ns(function() { with (FBL) { function HelloWorld ...

  6. Css Hack 大全(IE6、IE7、IE8、IE9 css hack)

    一.IE6 css hack: 1. *html Selector {} /* Selector 表示 css选择器 下同 */ 2. Selector { _property: value; } / ...

  7. mysql数据库备份/恢复

    备份数据库(进入Mysql bin目录下/C:\Program Files\MySQL\MySQL Server 5.6\bin)本地安装mysql数据库 备份表结构及数据 mysqldump -hl ...

  8. ctrl+shift+f

    ctrl+f是在当前文件寻找某个参数 ctrl+shift+f是在整个工程目录下寻找某个参数

  9. python之道13

    看代码分析结果 func_list = [] for i in range(10): func_list.append(lambda :i) v1 = func_list[0]() v2 = func ...

  10. 安装 Win7 的系统的时候如何分区

    解决方案 在安装Win7的系统的时候,可以使用下面方法进行分区: 1. 在出现同意许可条款,勾选“我接受许可条款(A)”后,点击下一步,然后继续下面操作: 2. 进入分区界面,点击“驱动器选项(高级) ...