SGU - 131 Hardwood floor (状态压缩)

题目大意:要求在n *m的网格上面铺满2 * 1的I型砖头活着2 * 2(缺了一个1 *1)的L型砖头,问有多少中铺法

解题思路:和POJ - 2411 Mondriaan’s Dream类似

这里用s1表示上一行的状态,s2表示当前行的状态,b1表示上一行的上一列是否对当前列有影响,b2表示当前行的上一列是否对当前列有影响

可得到一张状态转换表

以上摘自这里写链接内容

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 10
#define S (1 << 12)
long long ans[N][N], dp[N][S];
int n, m;

void init() {

    int t;
    if (n < m) {
        t = n;
        n = m;
        m = t;
    }
    memset(dp, 0, sizeof(dp));
    dp[0][(1 << m) - 1] = 1;
}

void dfs(int r, int c, int s1, int s2, int b1, int b2) {
    if (c == m) {
        if (!b1 && !b2) {
            dp[r][s2] += dp[r - 1][s1];
        }
        return ;
    }
    if (!b1 && !b2) {
        dfs(r, c + 1, s1 << 1, (s2 << 1) | 1, 0, 0);
        dfs(r, c + 1, s1 << 1, (s2 << 1) | 1, 1, 0);
        dfs(r, c + 1, s1 << 1, (s2 << 1) | 1, 0, 1);
    }

    if(!b1)
        dfs(r, c + 1, s1 << 1, (s2 << 1) | b2, 1, 1);
    if(!b2) {
        dfs(r, c + 1, (s1 << 1) | (1 - b1), (s2 << 1) | 1, 0, 1);
        dfs(r, c + 1, (s1 << 1) | (1 - b1), (s2 << 1) | 1, 1, 1);
    }
    dfs(r, c + 1, (s1 << 1) | (1 - b1), (s2 << 1) | b2, 0, 0);
}

void solve() {
    for(int i = 1; i <= n; i++)
        dfs(i,0,0,0,0,0);
    printf("%lld\n", ans[n][m] = ans[m][n] = dp[n][(1 << m) - 1]);
}

int main() {
    memset(ans, -1, sizeof(ans));
    while(scanf("%d%d", &n, &m) != EOF) {
        if(ans[n][m] != -1) {
            printf("%lld\n", ans[n][m]);
            continue;
        }
        init();
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 09:30:32

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

SGU 131.Hardwood floor 状态压缩DP

#include <cstdio> #include <cstring> typedef __int64 LL; LL dp[10][1<<10]; int n, m; int st, flag; void dfs(int i, int s, int ns, int j, LL num) { if(j == m) { dp[i+1][ns] += num; return; } if((s&(1<<j)) == 0) { if(ns&(1<

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改变某个银行的存款.该村子在财产上的求和运算等同于我们的乘法运算,也就是说领袖开户时的存款总