• POJ 2411 Mondriaan's Dream:网格密铺类 状压dp


    题目链接:http://poj.org/problem?id=2411

    题意:

      给你一个n*m的网格 (1<=n,m<=11) ,往里面铺1*2或2*1的砖块,问你铺完这个网格有多少种不同的方法。

     

    题解:

      表示状态:

        dp[state][i] = num of ways at ith row

        (1)当前铺到了第i行

        (2)在铺第i行之前,第i行已经被占的格子状态为state

      如何转移:

        对于当前第i行的第j列处,有三种情况:

        (1)竖着铺。i+1行的第j个位置会被占,在这一行占用了一个宽度,接下来该在第j+1列铺。

        (2)横着铺。对i+1行没有影响,在这一行占用了两个宽度,接下来该在j+2列铺。

        (3)已经被占。只能不铺,对i+1行没有影响,接下来该在第j+1列铺。

        所以在求dp之前先暴搜出在一行上的每个状态state铺完之后下一行的状态,存到vector中。

        转移:枚举每一行i,当前行的state,以及当前state能够转移的状态nex。

          dp[nex][i+1] += dp[state][i]

     

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <vector>
     5 #define MAX_N 15
     6 #define MAX_S (1<<12)
     7 
     8 using namespace std;
     9 
    10 int n,m;
    11 long long dp[MAX_S][MAX_N];
    12 vector<int> shift[MAX_S];
    13 
    14 void dfs(int col,int state,int nex)
    15 {
    16     if(col==m)
    17     {
    18         shift[state].push_back(nex);
    19         return;
    20     }
    21     if((state>>col)&1)
    22     {
    23         dfs(col+1,state,nex);
    24         return;
    25     }
    26     dfs(col+1,state,nex|(1<<col));
    27     if(col+1<m && !((state>>(col+1))&1)) dfs(col+2,state,nex);
    28 }
    29 
    30 int main()
    31 {
    32     while(cin>>n>>m)
    33     {
    34         if(n==0 && m==0) break;
    35         for(int state=0;state<(1<<m);state++)
    36         {
    37             shift[state].clear();
    38         }
    39         for(int state=0;state<(1<<m);state++)
    40         {
    41             dfs(0,state,0);
    42         }
    43         memset(dp,0,sizeof(dp));
    44         dp[0][0]=1;
    45         for(int i=0;i<n;i++)
    46         {
    47             for(int state=0;state<(1<<m);state++)
    48             {
    49                 if(dp[state][i])
    50                 {
    51                     for(int j=0;j<shift[state].size();j++)
    52                     {
    53                         int nex=shift[state][j];
    54                         dp[nex][i+1]+=dp[state][i];
    55                     }
    56                 }
    57             }
    58         }
    59         cout<<dp[0][n]<<endl;
    60     }
    61 }
  • 相关阅读:
    cmd的操作命令导出导入.dmp文件
    转:String数组初始化
    Oracle计算时间差
    WEB-INF目录与META-INF目录的作用
    【神乎其神】这些EXCEL技巧,太神奇了,赶紧收藏!
    报错: The type ByteInputStream is not accessible due to restriction on required library
    ModelAndView对象作用
    shiro使用
    包装类型的比较,如:Integer,Long,Double
    转一个distinct用法,很有帮助
  • 原文地址:https://www.cnblogs.com/Leohh/p/7368670.html
Copyright © 2020-2023  润新知