zoukankan      html  css  js  c++  java
  • SGU131

    题目大意

    给定一个N*M大小的矩形,要求你用1*2和2*2(缺个角)的砖块把矩形铺满(不能重叠),问总共有多少种铺法?

    题解

    受POJ2411的影响,怎么都没想到3,4,5,6这几种情况该怎么放置,看了网上大牛的解题报告和代码(真是不好的习惯,可是太弱了就是想不出咋办%>_<%)之后豁然开朗~~~~

    规模比较小,所以用状态压缩DP来搞,是POJ2411加强版。有以下几种铺法:

    ##     #.     ##    ##     #.   .#
    ..     #.     #.    .#     ##   ##
    1      2      3      4      5    6
    还有一种情况就是不放~~~
    我们依然是枚举出合法的当前行以及上一行,不过这里要比POJ2411稍微麻烦点,因为1,3,4,5,6这五种情况当前列的放置会影响后面一列的放置,
    所以我们还需要用两个变量来记录是否对下一行有影响,然后就是根据这两个变量的情况进行相应的砖块放置。

    代码:

    纯模仿。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define MAXN 10
    typedef long long LL;
    LL dp[MAXN][1<<MAXN];
    int n,m;
    void dfs(int step,int s1,int s2,int u1,int u2,int line)
    {
        if(step==m)
        {
            if(!u1&&!u2) dp[line][s2]+=dp[line-1][s1];
            return;
        }
        if(!u2)
        {
            if(!u1)
            {
                dfs(step+1,s1<<1,s2<<1|1,0,0,line);
                dfs(step+1,s1<<1,s2<<1|1,1,0,line);
                dfs(step+1,s1<<1,s2<<1|1,0,1,line);
            }
            dfs(step+1,(s1<<1|1)-u1,s2<<1|1,0,1,line);
            dfs(step+1,(s1<<1|1)-u1,s2<<1|1,1,1,line);
        }
        if(!u1)dfs(step+1,s1<<1,s2<<1|u2,1,1,line);
        dfs(step+1,(s1<<1|1)-u1,s2<<1|u2,0,0,line);
    }
    int main ()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
    
            memset(dp,0,sizeof(dp));
            dp[0][(1<<m)-1]=1;
            for(int i=1; i<=n; i++)
                dfs(0,0,0,0,0,i);
            printf("%I64d
    ",dp[n][(1<<m)-1]);
        }
        return 0;
    }
  • 相关阅读:
    bzoj 3339 莫队
    E. XOR and Favorite Number
    HDU 2222 AC自动机
    SPOJ 694 不同子串个数
    Codeforces Round #428 (Div. 2)
    HDU 6103
    《贪婪的动态规划》
    《浅谈图论模型的建立与应用》
    bzoj 2194 快速傅里叶之二
    java中高级面试题整理及参考答案
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3455201.html
Copyright © 2011-2022 走看看