题目描述

有一个m行n列的矩阵,用1*2的骨牌(可横放或竖放)完全覆盖,骨牌不能重叠,有多少种不同的覆盖的方法? 你只需要求出覆盖方法总数mod p的值即可。

输入格式

三个整数数n,m,p,m<=5,p<=10000,n<=10000

输出格式

一个整数:总数模p的结果


不难想到可以用状压来做这题。设dp(i,j)表示第i列放置情况为j的二进制表示,其中j的第k位为1时表示这玩意是一块竖着的骨牌的上半部分,为0则是其余的情况。我们考虑一下dp(i,j)可以由哪些状态转移而来。

设上一行的二进制表示为j,当前一行的为k。由于当j的某些位置为1时,k的这些位置也必须为1。为了在满足我们的定义的同时把j的1给转移下来,我们可以将j和k做一次按位或运算。此时数j|k中为0的部分就是放横着的骨牌的地方。显然j|k中为0的连续部分长度必须是偶数。所以我们转移的第一个条件就是:

1.j|k的每一段连续0的长度都必须为偶数

如果上一行的某一位是1,而当前一行的这一位也是1,那么不合法,不能转移。所以我们的第二个转移的条件就是:

2.j和k的相同位置不能都为1

怎么判断两个条件呢?

对于第二个条件,我们可以将j和k做一次按位与运算,如果得到的数不为0,即得到的数里面含有1,那么不合法:

if(j&k) continue;

对于第一个条件,我们只好O(m)地慢慢转移:

int odd=0,cnt=0;
for(register int l=0;l<m;l++)
if((j|k)>>l&1) odd|=cnt,cnt=0;
else cnt^=1;
if(odd|cnt) continue;

所以我们得到了一个时间复杂度为O(NM * 2^M * 2^M)=O(NM * 4^M)的算法。

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxm 5
#define maxn 10001
using namespace std; int dp[maxn][1<<maxm];
int n,m,p; inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
} int main(){
n=read(),m=read(),p=read();
dp[0][0]=1;
for(register int i=1;i<=n;i++){
for(register int j=0;j<1<<m;j++){
for(register int k=0;k<1<<m;k++){
if(j&k) continue;
int odd=0,cnt=0;
for(register int l=0;l<m;l++)
if((j|k)>>l&1) odd|=cnt,cnt=0;
else cnt^=1;
if(odd|cnt) continue;
(dp[i][j]+=dp[i-1][k])%=p;
}
}
}
printf("%d\n",dp[n][0]);
return 0;
}

这个复杂度足够通过本题了。


对于这个算法有个小小的优化:

设函数f(j,k)=j|k,不难发现其定义域大小为2M2=4M而值域大小只有2M,所以我们对于一个f(j,k)其实重复算了2^M次。所以我们可以预处理出所有f(j,k):

for(register int i=0;i<1<<m;i++){
int odd=0,cnt=0;
for(register int j=0;j<m;j++)
if(i>>j&1) odd|=cnt,cnt=0;
else cnt^=1;
even[i]=odd|cnt?0:1;
}

然后在dp的过程中:

dp[0][0]=1;
for(register int i=1;i<=n;i++){
for(register int j=0;j<1<<m;j++){
for(register int k=0;k<1<<m;k++){
if(!(j&k)&&even[j|k]) (dp[i][j]+=dp[i-1][k])%=p;
}
}
}

可以把时间复杂度优化成O(N * 4^M+M * 2^M)

Zju1100 Mondriaan的更多相关文章

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

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

  2. POJ 题目2411 Mondriaan's Dream(状压DP)

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

  3. POJ 2411 Mondriaan&#39;s Dream

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

  4. POJ2411 Mondriaan's Dream

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

  5. 状压DP POJ 2411 Mondriaan'sDream

    题目传送门 /* 题意:一个h*w的矩阵(1<=h,w<=11),只能放1*2的模块,问完全覆盖的不同放发有多少种? 状态压缩DP第一道:dp[i][j] 代表第i行的j状态下的种数(状态 ...

  6. HDU 1400 (POJ 2411 ZOJ 1100)Mondriaan's Dream(DP + 状态压缩)

    Mondriaan's Dream Problem Description Squares and rectangles fascinated the famous Dutch painter Pie ...

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

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

  8. poj 2411 Mondriaan&#39;s Dream 【dp】

    题目:id=2411" target="_blank">poj 2411 Mondriaan's Dream 题意:给出一个n*m的矩阵,让你用1*2的矩阵铺满,然 ...

  9. POJ2411 Mondriaan's Dream(状态压缩)

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

随机推荐

  1. css进阶 03-网页设计和开发中,关于字体的常识

    03-网页设计和开发中,关于字体的常识 #前言 我周围的码农当中,有很多是技术大神,却常常被字体这种简单的东西所困扰. 这篇文章,我们来讲一讲关于字体的常识.这些常识所涉及到的问题,有很强的可操作性, ...

  2. node目录

    1 [了解nodejs] 1.1 [node简介] 1.2 [node的特点] 1.3 [如何安装] 1.4 [如何运行] 2 [es6--基本语法] 2.1 [变量的解构赋值] 2.2 [解构赋值] ...

  3. 浅谈强连通分量(Tarjan)

    强连通分量\(\rm (Tarjan)\)             --作者:BiuBiu_Miku \(1.\)一些术语   · 无向图:指的是一张图里面所有的边都是双向的,好比两个人打电话 \(U ...

  4. robotframework中的参数展开

    robot调用关键字传参的方式是用分隔符分开不同参数,如 keyword arg1 arg2 arg3 arg4 当参数中传入了使用@符号的列表变量时,@符号会将列表展开: @{list1}= Cre ...

  5. CSS鼠标指针cursor样式

    参考来源:W3SCHOOL 有时我们需要在CSS布局时设定特定的鼠标指针样式,这时可以通过设定cursor来实现: url: 需使用的自定义光标的 URL. 注释:请在此列表的末端始终定义一种普通的光 ...

  6. [C#] (原创)进度等待窗口(附:自定义控件的使用)

    一.前言 技术没有先进与落后,只有合适与不合适. 在程序当中,经常有耗时较长的操作,为了给用户更好的体验,就需要给用户一个及时的反馈,这种时候就需要用到进度等待窗口. 实现进度等待窗口的技术有很多,比 ...

  7. 初识Web Service

    Web Service 今天新接了一个小项目,要用webservice.把示例代码拿过来一看,我有点懵.这啥东西?虽然调试了一下,找猫画虎也算调成功了,但是对这个webservice还是不太了解. 下 ...

  8. Spring Boot 有哪些优点?

    a.减少开发,测试时间和努力. b.使用 JavaConfig 有助于避免使用 XML. c.避免大量的 Maven 导入和各种版本冲突. d.通过提供默认值快速开始开发.没有单独的 Web 服务器需 ...

  9. 记一次由于引用第三方服务导致的GC overhead limit exceeded异常

    最近笔者遇到一个问题  监控平台忽然告警 GC overhead limit exceeded 这个异常 第一反应估计是堆溢出了.于是各种各种jmap  jstack下载堆栈文件和堆日志文件. 以下是 ...

  10. 初探JAVA内部类细节一

    定义: 可以将一个类的定义放在另一个类的内部 这就是内部类.--摘自java编程思想 一般实现方式: public class SimpleInnerClass { class Content { p ...