Hardwood floor - SGU 131(状态压缩)

题目大意:用 2*1 或者2*2-1的格子覆盖M*N的矩阵,有多少种覆盖方式。

分析:容易知道有以下6种放置方式。

然后用深搜的方法直接搞出来就行了,不过要使用两个变量来判断本位是否受影响。如果本行的放置可以影响上一行,比如(1,3,4,5,6)那么所影响的位置为0,如果没有受到影响那么就是1。

代码如下:

=====================================================================================================================

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

const int MAXN = 12;
const int Bit = 9;

long long dp[MAXN][1<<Bit];
int M, N;

void DFS(int row, int col, int now, int pre, bool uNow, bool uPre)
{///row表示所在行,col表示列,now表示本行的状态,pre表示上一行的状态
 ///uNow uPre表示本列和上一列是否收到影响,1表示受影响,0表示没有
    if(col == N)
    {
        if(!uNow && !uPre)
            dp[row][now] += dp[row-1][pre];
        return ;
    }

    if(!uNow)
    {
        if(!uPre)
        {
            DFS(row, col+1, now<<1|1, pre<<1, 0, 0);
            DFS(row, col+1, now<<1|1, pre<<1, 1, 0);
            DFS(row, col+1, now<<1|1, pre<<1, 0, 1);
        }
        DFS(row, col+1, now<<1|1, pre<<1|(!uPre), 1, 0);
        DFS(row, col+1, now<<1|1, pre<<1|(!uPre), 1, 1);
    }
    if(!uPre)
        DFS(row, col+1, now<<1|uNow, pre<<1, 1, 1);
    DFS(row, col+1, now<<1|uNow, pre<<1|(!uPre), 0, 0);
}

int main()
{
    scanf("%d%d", &M, &N);

    dp[0][(1<<N)-1] = 1;
    for(int i=1; i<=M; i++)
        DFS(i, 0, 0, 0, 0, 0);

    printf("%lld\n", dp[M][(1<<N)-1]);

    return 0;
}
时间: 2024-10-23 13:45:33

Hardwood floor - SGU 131(状态压缩)的相关文章

SGU 131.Hardwood floor

时间限制:0.25s 空间限制:4M 题意: 给出 n*m (1≤n.m≤9)的方格棋盘,用 1*2 的矩形的骨牌和 L 形的(2*2 的 去掉一个角)骨牌不重叠地覆盖,求覆盖满的方案数. Solution:              还是状态压缩,这次的情况比较多,要全部列出.              b1,b2分别代表上下两行前列对下一列的影响              s1,s2对应上下两行的状态 情况 上列b1,b2要求 状态改变 对下一列的影响 10 10 b1=0, b2=0; s

状态压缩动态规划总结

状态压缩是一个很广的概念,在OI中也有很多的应用,当我们把他应用到动态规划中,可以用来精简状态,节约空间,也方便转移.最常见的就是用二进制来表是状态,利用各种位移运算,就可以实现\(O(1)\)的转移.状压DP适用于“窄棋盘”上的DP,否则状态太多无法存下. POJ1185 炮兵阵地 题意:给一个\(N \times M\)的地形盘,有平原和山坡,要求在平原上部署尽量多的炮(攻击范围2),使得不互相攻击. 数据范围:N <= 100:M <= 10,符合条件.如何表示状态?按行DP,一个二进制

HDU 5023 A Corrupt Mayor&#39;s Performance Art 线段树区间更新+状态压缩

Link:  http://acm.hdu.edu.cn/showproblem.php?pid=5023 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <cmath> 8 using namesp

SRM 513 2 1000CutTheNumbers(状态压缩)

SRM 513 2 1000CutTheNumbers Problem Statement Manao has a board filled with digits represented as String[] board. The j-th character of the i-th element of board represents the digit written in cell in row i, column j of the board. The rows are numbe

SRM 628 DIV2 1000 CandleTimerEasy 状态压缩+DFS

题意:给你一个树型蜡烛,你可以从1个或多个叶子开始点蜡烛,问你能使蜡烛烧完以后能得到时间的个数. 解题思路:状态压缩枚举DFS, 解题代码: 1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "CandleTimerEasy.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include

hdu 4568(状态压缩dp)

题意:一张n*m的网格内每个点有话费,还有若干个宝藏,问一个人要走进去拿走所有宝藏在走出来的最小花费. 思路:看宝藏只有13个直接想到了状压dp[i][j]拿了哪几个前一个为j的最小花费,先bfs+优先队列预处理出最短路,然后记忆化搜索就可. 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao

【汉密尔顿、DP|状态压缩】POJ-2288 Islands and Bridges

Islands and Bridges Time Limit: 4000MS   Memory Limit: 65536K       Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we all know, is a path along the bridges such that it visits each island exactly once.

清华集训 2014--奇数国(线段树&amp;欧拉函数&amp;乘法逆元&amp;状态压缩)

昨天想了一晚...早上AC了... 这么长时间没打线段树,这回居然一次过了... 感觉数论方面应该已经没有太大问题了... 之后要开始搞动态规划之类的东西了... 题意 在一片美丽的大陆上有100000个国家,记为1到100000.这里经济发达,有数不尽的账房,并且每个国家有一个银行.某大公司的领袖在这100000个银行开户时都存了3大洋,他惜财如命,因此会不时地派小弟GFS清点一些银行的存款或者让GFS改变某个银行的存款.该村子在财产上的求和运算等同于我们的乘法运算,也就是说领袖开户时的存款总

【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋

一.写在前面 其实这是一道大水题,而且还出在了数据最水的OJ上,所以实际上这题并没有什么难度.博主写这篇blog主要是想写下一个想法--状态压缩.状态压缩在记录.修改状态以及判重去重等方面有着极高的(←_←词穷了,诸位大致理解一下就好)效率.博主原本打算在blog介绍一种DP--状态压缩型动态规划,但动笔(键盘??)前,博主突然想起自己前些年写过的一道广搜题,当时在判重方面冥思苦想想出了一种类似状态压缩的方法,开心了好久,于是在此先抛砖引玉为状压DP做个铺垫. 二.题目 Description