超经典的一道题目,实现这题的方法也有非常多种

1.利用DFS建立矩阵,然后通过高速矩阵幂得到答案(运用于min(m,n)比較小。可是max(m,n)很大的情况)

2.利用dp状压解决

第一种在我的还有一篇博客里有

http://blog.csdn.net/qwb492859377/article/details/47138821

我们在这里讨论另外一种方法。

刘汝佳的算法训练指南中384页介绍了一种复杂度O(mn*2^m)的方法,这个复杂度实在是太小了。

我对着上面敲结果仅仅用了32ms就过了这题,然后花了非常久才看懂(蒟蒻)

他的状态并非一整行一整行的。。所以一開始我就陷入了误圈。

第二,,他代码里有个1<<m,我一直没搞清楚。究竟他的下标是从0開始还是从1開始,怎么会出现1<<m呢。事实上这是上一次的1<<m-1。由于他把状态先左移过一次-_-....

我依据我的理解讲下代码

(i,j)表示以这个格子为右下角,要不要放骨牌以及放那种骨牌. k表示在(i,j)之前的连续m个方块的状态,0表示没放,1表示已经放了,当中靠近(i,j)的下标是0

先枚举,i再枚举j,最后枚举k,也就是红色表示的区域

假设(i,j)不放。那么它上面那一个就必须已经放过了,换句话说,仅仅有k&(1<<(m-1)) 。k才有资格将状态转移到新的状态(k<<1)^(1<<m)

这个状态就是左移后。把曾经的第一位去掉。然后在最后面补上一个0,相当于红色区域所有向右挪了一个单位。

假设(i,j)放竖直的骨牌,那么i不能为0,且!k&(1<<(m-1))满足。才干考虑把k状态转移到新的状态k << 1 | 1去

假设(i,j)放横向的骨牌,那么j不能为0,且!(k&1)&&(1<<(m-1)) 也就是k的最后一个要是空着的。并且(i,j)上面一个必须是1。这样才干横向放后上面的不会存在空着的。

刚開始我还在思考,应该(i-1,j-1)也应该要是1才干够把。,可是后来想了一下。那个位置一定会是1,否则(i,j)左边那个位置就不可能是0了。由于仅仅能通过第一种情况转移过来

所以当满足这些条件时,k能转移到新状态(k<<1)^(1<<m)|3上来

语言表达能力有限,,,来看代码把,,感觉刘汝佳那份代码尽管写起来非常工整清晰。反而有些地方变得非常难理解了

然后dp利用滚动数组,得到的状态向后更新答案的方式,就能攻克了

#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<functional>
#include<algorithm> using namespace std;
typedef long long LL;
typedef pair<int, int> PII; const int MX = 3000 + 5;
const int INF = 0x3f3f3f3f; int m, n;
LL dp[2][MX]; int main() {
//freopen("input.txt","r",stdin);
while(~scanf("%d%d", &m, &n), m + n) {
memset(dp, 0, sizeof(dp));
if(m > n) swap(m, n); int cur = 0, nxt = 1;
dp[cur][(1 << m) - 1] = 1; for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
memset(dp[nxt], 0, sizeof(dp[nxt])); for(int k = 0; k < (1 << m); k++) {
if(k & (1 << (m - 1))) dp[nxt][(k << 1) ^ (1 << m)] += dp[cur][k];//不放
if(i && !(k & (1 << (m - 1)))) dp[nxt][k << 1 | 1] += dp[cur][k];//竖着放
if(j && !(k & 1) && (1 << (m - 1))) dp[nxt][(k << 1) ^ (1 << m) | 3] += dp[cur][k];//横着放
}
swap(cur, nxt);
}
}
printf("%I64d\n", dp[cur][(1 << m) - 1]);
}
return 0;
}

状压dp Mondriaan&#39;s Dream poj2411的更多相关文章

  1. POJ 2411 Mondriaan&#39;s Dream

    状压DP Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9938 Accepted: 575 ...

  2. [poj2411] Mondriaan's Dream (状压DP)

    状压DP Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nigh ...

  3. [Poj2411]Mondriaan's Dream(状压dp)(插头dp)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18096   Accepted: 103 ...

  4. poj2411 Mondriaan's Dream (轮廓线dp、状压dp)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17203   Accepted: 991 ...

  5. poj2411 Mondriaan's Dream[简单状压dp]

    $11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...

  6. POJ2411 Mondriaan's Dream 【状压dp】

    没错,这道题又是我从LZL里的博客里剽过来的,他的题真不错,真香. 题目链接:http://poj.org/problem?id=2411 题目大意:给一个n * m的矩形, 要求用 1 * 2的小方 ...

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

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

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

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

  9. POJ 2411 Mondriaan's Dream ——状压DP 插头DP

    [题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...

随机推荐

  1. Problem J: 零起点学算法89——程序设计竞赛

    #include<stdio.h> //选择排序法 int main(){ ]; while(scanf("%d",&n)!=EOF){ ;i<n;i++ ...

  2. NOIP模拟·20141105题解

    [A.韩信点兵] 结论题+模板题,用到了中国剩余定理,维基百科上讲的就比较详细,这里就不再赘述了…… 对于这题,我们先利用中国剩余定理($x \equiv \sum{(a_i m_i (m_i^{-1 ...

  3. Linux通用KVM自动安装Shell脚本(兼容所有Linux发行版/CentOS/Ubuntu)

    官网: https://github.com/retspen/webvirtmgr/wiki/Setup-Host-Server 安装: wget -O - https://retspen.githu ...

  4. javacripr基础总结

    js中一切皆为对象 方法=函数 其实也是内建对象 函数都可以用,包括数组,函数 都可以获取 核心dom编程 -- dom d document文档 o 对象 1用户自定义对象, 2内建对象  如Arr ...

  5. 让你的WPF程序在Win7下呈现Win8风格主题

    今天在Win8下使用了一个我之前写的一个WPF程序的时候,发现现在也支持Win8效果了(记得以前的.net 4.0的版本是不支持的).由于WPF的控件是自绘的,并不受系统主题所控制,也就是说.net ...

  6. Inno Setup入门(二十二)——Inno Setup类参考(8)

    http://379910987.blog.163.com/blog/static/33523797201121331832201/ 列表框 列表框(ListBox)是Windows应用程序中重要的输 ...

  7. ylbtech-LanguageSamples-Nullable(可以为 null 的类型)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Nullable(可以为 null 的类型) 1.A,示例(Sample) 返回顶部 “ ...

  8. Make Menuconfig详解 (配置内核选择)

    Make Menuconfig简介 make menuconfig 图形化的内核配置make mrproper -----删除不必要的文件和目录. #make config(基于文本的最为传统的配置界 ...

  9. Hadoop 伪分布式上安装 HBase

    hbase下载:点此链接  (P.S.下载带bin的) 下载文件放入虚拟机文件夹,打开,放在自己指定的文件夹 -src.tar.gz -C /home/software/ 修改环境配置 gedit / ...

  10. 组件prop检验

    Vue.js中的父子组件相信都已经是大家很常用到的功能了, 父组件通过props属性向子组件传值子组件通过自定义事件向父组件传值 那么我们怎么去校验props属性中的类型呢 笔者列出以下几种方法: 1 ...