【BZOJ2331】[SCOI2011]地板 插头DP

【BZOJ2331】[SCOI2011]地板

Description

lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西。小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板。现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案?

需要注意的是,如下图所示,L型地板的两端长度可以任意变化,但不能长度为0。铺设完成后,客厅里面所有没有柱子的地方都必须铺上地板,但同一个地方不能被铺多次。

Input

输入的第一行包含两个整数,R和C,表示客厅的大小。

接着是R行,每行C个字符。’_’表示对应的位置是空的,必须铺地板;’*’表示对应的位置有柱子,不能铺地板。

Output

输出一行,包含一个整数,表示铺满整个客厅的方案数。由于这个数可能很大,只需输出它除以20110520的余数。

Sample Input

2 2
*_
__

Sample Output

1

HINT

R*C<=100

题解:我们取R和C中小的那维做状态。显然状态是三维的:对于轮廓线上的每个位置,用0表示无插头,1表示有插头,并且这个L还没有拐弯,2表示有插头,并且L已经拐弯了。然后进行3*3的讨论吧!注意一个拐过弯的插头可以停止,一个没拐过弯的插头可以拐弯。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=177200;
const int P=20110520;
int n,m,k,tag,tot;
char str[110][110];
int dp[2][maxn],bt[20],m3[maxn];
inline void upd(int a) {dp[k][a]+=tag;	if(dp[k][a]>=P)	dp[k][a]-=P;}
int main()
{
	scanf("%d%d",&n,&m);
	int i,j,S,T,p,q,x,y;
	for(i=1;i<=n;i++)	scanf("%s",str[i]+1);
	if(n<m)
	{
		for(i=1;i<=m;i++)	for(j=1;j<i;j++)	swap(str[i][j],str[j][i]);
		swap(n,m);
	}
	for(i=bt[0]=1;i<=m+1;i++)	bt[i]=bt[i-1]*3;
	for(tot=bt[m+1],i=1;i<tot;i++)	m3[i]=i%3;
	dp[0][0]=1;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			k^=1;
			memset(dp[k],0,sizeof(dp[k]));
			for(S=0;S<tot;S++)	if(dp[k^1][S])
			{
				x=bt[j-1],y=bt[j],p=m3[S/x],q=m3[S/y],tag=dp[k^1][S],T=S-x*p-y*q;
				if(str[i][j]==‘*‘)
				{
					if(!p&&!q)	upd(T);
					continue;
				}
				if(!p&&!q)
				{
					if(i!=n&&j!=m)	upd(T+((x+y)<<1));
					if(i!=n)	upd(T+x);
					if(j!=m)	upd(T+y);
				}
				if(!p&&q==1)
				{
					if(i!=n)	upd(T+x);
					if(j!=m)	upd(T+(y<<1));
				}
				if(!p&&q==2)
				{
					if(i!=n)	upd(T+(x<<1));
					upd(T);
				}
				if(!q&&p==1)
				{
					if(j!=m)	upd(T+y);
					if(i!=n)	upd(T+(x<<1));
				}
				if(!q&&p==2)
				{
					if(j!=m)	upd(T+(y<<1));
					upd(T);
				}
				if(p==1&&q==1)	upd(T);
			}
		}
		for(S=tot-1;S>=0;S--)	dp[k][S]=(m3[S]>0)?0:dp[k][S/3];
	}
	printf("%d",dp[k][0]);
	return 0;
}//10 10 __________ __________ __________ __________ __________ __________ __________ __________ __________ __________
时间: 2024-08-10 19:07:23

【BZOJ2331】[SCOI2011]地板 插头DP的相关文章

【BZOJ】2331: [SCOI2011]地板 插头DP

[题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表示无插头,1表示能拐弯的插头,2表示不能拐弯的插头.(有插头,方块就必须必须延伸到该格),考虑转移即可. 注意可以凭空产生一个能拐弯的插头. n*m<=100,当m>10的时候将i,j互换. #include<cstdio> #include<cstring> #inclu

2331: [SCOI2011]地板 插头DP

国际惯例的题面:十分显然的插头DP.由于R*C<=100,所以min(R,C)<=10,然后就可以愉悦地状压啦.我们用三进制状压,0表示没有插头,1表示有一个必须延伸至少一格且拐弯的插头,2表示有一个必须延伸一格且不可以拐弯的插头.转移的话就十分显然了.00->22,表示用这个格子作为开始的拐角.00->10,表示用这个格子向下延伸.00->01,表示用这个格子向右延伸.01->10,表示这个格子连接上下.01->02,表示在这个格子作为中间的拐角.02->

bzoj 2331: [SCOI2011]地板 插头dp

用四进制表示状态. 用hash表把一个四进制数映射到一个小数上. 这样就可以memset了. 转移的时候分类讨论一下,特判下边界情况. 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #define bq 1<<bit[j] 6 #define bp 1<<bit[j-1] 7 using namespace std

bzoj2331 : [SCOI2011]地板 2011-12-20

2331: [SCOI2011]地板Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 128  Solved: 54[Submit][Status][Discuss]Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板.现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案? 需要注意的是,如下图所示,L型地板的两端长度可

插头dp题表(已完成)

bzoj1814: Ural 1519 Formula 1 bzoj3125: CITY bzoj1210: [HNOI2004]邮递员 bzoj2331: [SCOI2011]地板 bzoj1187: [HNOI2007]神奇游乐园 bzoj2310: ParkII 原文地址:https://www.cnblogs.com/TSHugh/p/8179245.html

P3272 [SCOI2011]地板(插头DP)

[题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] (版权所有) https://www.luogu.org/blog/dedicatus545/solution-p3272 第一种情况:当前状态下,当前格子上方和左方都没有插头 这时我们需要找一个L形来把这个格子填上,那么我们可能有三种决策: 决策一:给这个格子加一个二号下插头和一个二号右插头,此时这

[入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样,并且有不少的分类讨论,让插头DP十分锻炼思维的全面性和严谨性. 下面我们一起来学习插头DP的内容吧! 插头DP主要用来处理一系列基于连通性状态压缩的动态规划问题,处理的具体问题有很多种,并且一般数据规模较小. 由于棋盘有很特殊的结构,使得它可以与“连通性”有很强的联系,因此插头DP最常见的应用要数

BZOJ 2331 地板(插头DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2331 题意:给出一个n*m的地面.有些是障碍.用L型的地板砖铺满.有多少种方案. 思路:用0表示没有插头,用1表示有插头且可以拐弯,用3表示有插头但是不能再拐弯了. 设有m列,轮廓线为[0,m].对于格子(i,j),设左插头x上插头y,那么转移有: (1)x=0,y=0:此时如图1-0,有三种转移,分别是1-1,1-2,1-3; (2)x!=0,y!=0:此时只有当x=y=1时可以转移

BZOJ2331:[SCOI2011]地板——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=2331 题面复制于洛谷 题目描述 lxhgww的小名叫”小L“,这是因为他总是很喜欢L型的东西.小L家的客厅是一个R*C的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板.现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案?需要注意的是,如下图所示,L型地板的两端长度可以任意变化,但不能长度为0. 铺设完成后,客厅里面所有没有柱子的地方都必须铺上地板,但同一个地方不