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;


s1<<1,

s2<<1|1;


b1=0,

b2=0;


11

10


b1=0,

b2=0;


s1<<1,

s2<<1|1;


b1=1,

b2=0;


10

11


b1=0,

b2=0;


s1<<1,

s2<<1|1;


b1=0,

b2=1;


00

11

b2=0;
s1<<1|1-b1,

s2<<1|1;


b1=0,

b2=1;


01

11

b2=0;
s1<<1|1-b1,

s2<<1|1;


b1=1,

b2=1;


11

01

b1=0;
s1<<1,

s2<<1|b2;


b1=1,

b2=1;


00

00


s1<<1|1-b1,

s2<<1|b2;


b1=0,

b2=0;

参考代码:

#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;
int n, m, x;
LL f[12][1 << 12];
//b1,b2,分别标记上一列队下一列的影响
void dfs (int k, int last, int now, int b1, int b2) {
	if (k == m){
              if(!b1&&!b2)
              f[x][now] += f[x - 1][last];
              return;
	}
	if (!b1 && !b2) {
		dfs (k + 1, last << 1 , now << 1 | 1, 0, 0);
		dfs (k + 1, last << 1 , now << 1 | 1, 1, 0);
		dfs (k + 1, last << 1 , now << 1 | 1, 0, 1);
	}
	if (!b1)
		dfs (k + 1, last << 1 , now << 1 | b2, 1, 1);
	if (!b2) {
		dfs (k + 1, last << 1 | (1-b1), now << 1 | 1, 0, 1);
		dfs (k + 1, last << 1 | (1-b1), now << 1 | 1, 1, 1);
	}
	dfs (k + 1, last << 1 | (1-b1), now << 1 | b2, 0, 0);
}
int main() {
	scanf ("%d %d", &n, &m);
	if (n < m) swap (n, m);
       f[0][ (1 << m) - 1] = 1;
	for ( x = 1; x <= n; x++)
		dfs (0, 0, 0, 0, 0);
	printf ("%lld", f[n][ (1 << m) - 1]);
}

  

SGU 131.Hardwood floor

时间: 2024-10-18 16:16:57

SGU 131.Hardwood floor的相关文章

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

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<

Hardwood floor - SGU 131(状态压缩)

题目大意:用 2*1 或者2*2-1的格子覆盖M*N的矩阵,有多少种覆盖方式. 分析:容易知道有以下6种放置方式. 然后用深搜的方法直接搞出来就行了,不过要使用两个变量来判断本位是否受影响.如果本行的放置可以影响上一行,比如(1,3,4,5,6)那么所影响的位置为0,如果没有受到影响那么就是1. 代码如下: ===============================================================================================

sgu 131 状压DP

棋盘覆盖(二) 时间限制:1000 ms  |  内存限制:65535 KB 描述 The banquet hall of Computer Scientists' Palace has a rectangular form of the size M x N (1<=M<=9, 1<=N<=9). It is necessary to lay hardwood floors in the hall. There are wood pieces of two forms:1) re

今日SGU 5.14

//SGU 131 还没完全想清楚 留坑 SGU 259 题意:一个机器处理n个任务,每个任务有时间t和传送时间l 收获:贪心 #include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" "; #define

今日SGU 5.15

最近事情好多,数据库作业,没天要学2个小时java,所以更新的sgu就比较少了 SGU 131 题意:给你两种小块一种,1*1,一种2*2-1*1,问你填满一个m*n的矩形有多少钟方法,n和m小于等于9, 收获:状态压缩,每一行都最多由上一行转移过来,因为上一行,那么最多有7情况,详情看代码 #include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl; #defin

sgu100~199题解

老东西了..发上来吧.. Sgu题解系列  南开中学邹事成 100:A+B略 101:Domino 给n块多米诺骨牌,每张骨牌两端各有从1到6的一个数字,现在要把这些骨牌排成一列,使相邻的两块骨牌相对的面所写的数字一样. 可以把每一块多米诺骨牌想象成一条边,把面上写的数字抽象成点,比如一块骨牌正面写的1反面写的2就想象成连了一条从1到2的边,那么这就是求一条有重边的欧拉回路了,dfs一下即可. 102:Coprimes给定n求从1到n中与n互质的数的个数. 可以把n质因数分解后直接代入欧拉函数.

poj 2411 Mondriaan&#39;s Dream(状压DP)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12232   Accepted: 7142 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

状态压缩动态规划总结

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