zoukankan      html  css  js  c++  java
  • 【POJ2411】Mondriaan's Dream

    题意:给一个n*m的方格,用1*2和2*1的方格填满,有多少种方案。n、m<=11。

    Sample Input

    1 2
    1 3
    1 4
    2 2
    2 3
    2 4
    2 11
    4 11
    0 0

    Sample Output

    1
    0
    1
    2
    3
    5
    144
    51205

    题解:我们发现n、m很小,状压dp即可,状态转移如下

     1 void dfs(int i,int j,int sta,int nex){
     2 //第i列、j+1行,当前状态sta,下列状态nex 
     3     if(j==n){f[i+1][nex]+=f[i][sta];return;}
     4     if(((1<<j)&sta)>0) dfs(i,j+1,sta,nex);
     5         //若此位置被上列占用,跳过 
     6     if(((1<<j)&sta)==0) dfs(i,j+1,sta,nex|(1<<j));
     7         //若此位置为空,尝试放1*2 
     8     if(j+1<n&&((1<<j)&sta)==0&&((1<<(j+1))&sta)==0) dfs(i,j+2,sta,nex);
     9         //若次位置及下个位置都空,尝试放2*1 
    10     return;
    11 }

    初始状态为f[1][0]=1,最终答案为f[m+1][0]。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 int n,m;
     6 long long f[20][2050];
     7 void dfs(int i,int j,int sta,int nex){
     8     if(j==n){f[i+1][nex]+=f[i][sta];return;}
     9     if(((1<<j)&sta)>0) dfs(i,j+1,sta,nex);
    10     if(((1<<j)&sta)==0) dfs(i,j+1,sta,nex|(1<<j));
    11     if(j+1<n&&((1<<j)&sta)==0&&((1<<(j+1))&sta)==0) dfs(i,j+2,sta,nex);
    12     return;
    13 }
    14 int main()
    15 {
    16     while(~scanf("%d%d",&n,&m)){
    17         if(!n&&!m) break;
    18         memset(f,0,sizeof(f));
    19         f[1][0]=1;
    20         for(int i=1;i<=m;i++)
    21             for(int j=0;j<(1<<n);j++)
    22                 if(f[i][j]) dfs(i,0,j,0);
    23         printf("%lld
    ",f[m+1][0]);
    24     }
    25     return 0;
    26 }
    
    
    
  • 相关阅读:
    三层架构补充
    复习三层架构
    复习DOM、JQuery
    复习HTML CSS JavaScript
    Git在新电脑拉github 上的项目
    超全的IE兼容性问题及解决方案
    JS操作iframe
    attachEvent和addEventListener
    HTTP 方法:GET 对比 POST
    原生JS+ CSS3创建loading加载动画;
  • 原文地址:https://www.cnblogs.com/Beginner-/p/8558450.html
Copyright © 2011-2022 走看看