题意:

用1*2和2*1的方块将给定长宽的矩形填满。问有多少种放法,对称的算两种。

分析:

状态压缩dp

首先用0表示前一行没有竖块占用这个位置,而1表示该位置和他上方的位置放了一个竖块,从而压缩状态。接下来一行一行的看,每一行都只受上一行的影响,同时影响着下一行的状态,那么如何将现在的状态和下一行的状态联系起来呢?

  1. 令dp[i][j]表示第i行状态为j时的方案数,直接把两个状态作为参数进行DFS,在到达每行行尾时更新 dp[i+1][next];。
  2. 看poj的discuss中的方法,对于某一行来说,如果横着放了方块后,就将相应的位置置为1,而被上一行占用的位置也已经是1了,那么整行下来,就只有0的位置是要放竖块的了,而此时下一行对应的位置应该为1,可以发现下一行状态就是这一行状态的非!【感觉好巧妙啊!

因为要求正好填满,所以两种方法最后都可以是输出dp[h+1][0],但是第二种方法也就可以取反直接用dp[h][(1<<w)−1]求。

还有!!位运算注意括号!!

代码:

方法一:

  1. #include<cstdio>
  2. #include<cstring>
  3. const int maxn = 15;
  4. long long dp[maxn][1<<maxn];
  5. int w, h;
  6. void dfs(int a, int b, int now, int next)
  7. {
  8. if(b == w){
  9. dp[a+1][next] += dp[a][now];
  10. return;
  11. }
  12. if(now&(1<<b)) dfs(a, b + 1, now, next);
  13. else {
  14. dfs(a, b+1, now, next|1<<b);
  15. if(b+1< w&&!(now&1<<(b+1)))
  16. dfs(a, b+2, now, next);
  17. }
  18. return;
  19. }
  20. int main (void)
  21. {
  22. while(~scanf("%d%d",&h,&w)&&h+w){
  23. memset(dp, 0, sizeof(dp));
  24. dp[1][0] = 1;
  25. dfs(1,0,0,0);
  26. for(int i = 2; i <= h; i++){
  27. for(int j = 0; j < 1<<w; j++){
  28. if(dp[i][j]) dfs(i, 0, j, 0);
  29. }
  30. }
  31. printf("%I64d\n",dp[h+1][0]);
  32. }
  33. }//266ms

方法二:

  1. #include<cstdio>
  2. #include<cstring>
  3. const int maxn = 15;
  4. long long dp[maxn][1<<maxn];
  5. int w, h;
  6. long long tmp;
  7. void dfs(int a, int b, int now)
  8. {
  9. if(b == w){
  10. dp[a][now] += tmp;
  11. return;
  12. }
  13. dfs(a, b + 1,now);//要么被占要么放竖块
  14. if(b+1<w&&!(now&1<<b)&&!(now&1<<(b+1)))
  15. dfs(a, b+2, now|(1<<b)|(1<<(b+1)));
  16. return;
  17. }
  18. int main (void)
  19. {
  20. while(~scanf("%d%d",&h,&w)&&h+w){
  21. memset(dp, 0, sizeof(dp));
  22. tmp = 1;
  23. dfs(1,0,0);
  24. for(int i = 2; i <= h; i++){
  25. for(int j = 0; j < 1<<w; j++){
  26. if(dp[i-1][j]) {
  27. tmp = dp[i-1][j];
  28. int next = ~j&((1<<w)-1);
  29. dfs(i, 0, next);
  30. }
  31. }
  32. }
  33. printf("%I64d\n",dp[h][(1<<w)-1]);
  34. }
  35. }//250MS

POJ 2411_Mondriaan's Dream的更多相关文章

  1. POJ 2411Mondriaan's Dream

    题目: Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after prod ...

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

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

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

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

  4. [poj P2411] Mondriaan's Dream

    [poj P2411] Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18023   A ...

  5. POJ 2411 Mondriaan's Dream 插头dp

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

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

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

  7. Mondriaan's Dream POJ - 2411

    Mondriaan's Dream POJ - 2411 可以用状压dp,但是要打一下表.暴力枚举行.这一行的状态.上一行的状态,判断如果上一行的状态能转移到这一行的状态就转移. 状态定义:ans[i ...

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

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

  9. POJ 2411 Mondriaan&#39;s Dream

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

随机推荐

  1. 深入学习数据结构之bitmap(四)

    Bitmap,今天我们来分析一下bitmap的实现原理以及它的使用场景. 一.使用场景: 1.对于大量数据(几千个数据的就不要在废话了),且无重复或者可以忽略重复的数字.为啥这里要强调无重复,因为在b ...

  2. jq星星评分

    html代码 <div class="make_mark"> <h5>请为这次服务打分</h5> <div class="mar ...

  3. leetcode:single-number-ii(Java位运算)

    题目 Given an array of integers, every element appears three times except for one. Find that single on ...

  4. SQL——时间戳

    mysql 低版本,date.datetime.timestamp 无法精确到毫秒 可以舍弃时间类型字段,用 bigint 来代替,如果用字符串类型代替,还是比较担心排序的时候只是根据第一个字母进行排 ...

  5. Matlab基础之单元数组和结构数组

    Matlab基础之单元数组和结构数组 前言: 单元数组和结构数组是一种新的数据类型,能将不同类型.不同维数的数组组合在一起,从而方便对不同的数据类型方便管理和维护. 如上图所示的2*2矩阵中,分别存储 ...

  6. Jmeter中的参数化常用的几种方式

    Jmeter中的参数化常用的几种方式,这里讲一下前两个方式,最后一个在csv参数化里已详细讲解. 1.用户参数 2.函数助手 3.CSV Data Set Config  一.用户参数 位置:添加-前 ...

  7. 最小生成树Prim算法 Kruskal算法

    Prim算法(贪心策略)N^2 选定图中任意定点v0,从v0开始生成最小生成树 树中节点Va,树外节点Vb 最开始选一个点为Va,其余Vb, 之后不断加Vb到Va最短距离的点 1.初始化d[v0]=0 ...

  8. swiper 旋转木马效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  9. 51nod 1175 区间第k大 整体二分

    题意: 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 分析: 仅仅就是一道整体二分的入门题而已,没听说过整体二分? 其实就是一个分治的函数 ...

  10. nginx虚拟主机配置实践

    1.配置基于域名的虚拟主机 [root@web01 html]# egrep -v "#|^$" /application/nginx/conf/nginx.conf.defaul ...