zoukankan      html  css  js  c++  java
  • HDU 1400 Mondriaan's Dream [状态压缩DP]

      题目问用1*2组成如图h*w矩形的方案有多少种。 

       

      明显的状态压缩DP,从上向下填充,假设两行的状态为stat1和stat2,则需要满足的条件是stat1|sta2=1<<w-1以及stat1&stat2中连续的1都是偶数个。因为上一行为空的下一行必须放一个竖的,而除去竖着到上一行的都是横着的,每一个横着的占的宽度都是2,所以stat1&stat2中连续的1肯定是偶数个。

      对每一层要记录一个状态是否搜过,并记录这个状态有多少种方法,即记忆化搜索。复杂度是O(h*(2^w)*(2^w))。

      斌牛的方法更为高效简洁,状态表示的是当前轮廓线的状态,复杂度是O(h*w*(2^w)),传送门在这里,http://www.cnblogs.com/staginner/archive/2012/09/04/2670729.html

     1 #include <string.h>
     2 #include <stdio.h>
     3 #include <set>
     4 typedef long long LL;
     5 int h,w,full;
     6 LL d[12][2200],res[12][12];
     7 int doublei(int state){
     8     for(int i=0,d=0;i<=w;i++)
     9         if(i<w&&((state>>i)&1))d++;
    10         else if(d&1)return 0;
    11     return 1;
    12 }
    13 LL dfs(int state,int step){
    14     if(d[step][state]!=-1)return d[step][state];
    15     if(step==h)return state==full-1;
    16     d[step][state]=0;
    17     for(int i=0;i<full;i++){
    18         if((i|state)!=full-1||!doublei(state&i))continue;
    19         d[step][state]+=dfs(i,step+1);
    20     }
    21     return d[step][state];
    22 }
    23 int main(){
    24      while(scanf("%d%d",&h,&w),h||w){
    25         if(res[w][h])printf("%I64d\n",res[w][h]);
    26         else{
    27             full=(1<<w);
    28             memset(d,-1,sizeof d);
    29             printf("%I64d\n",res[w][h]=res[h][w]=dfs(full-1,0));
    30         }
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    聚合物钽电容和普通钽电容的区别
    Java命令:Jstack
    计算并发用户数的五种方法
    LoadRunner脚本优化-加密与解密
    如何定位性能瓶颈
    loadrunner配置多台负载机设置
    nmon监控及简要分析
    Web系统大规模并发——电商秒杀与抢购
    大型网站的灵魂——性能
    mycat实战之性能测试
  • 原文地址:https://www.cnblogs.com/swm8023/p/2671158.html
Copyright © 2011-2022 走看看