http://www.lydsy.com/JudgeOnline/problem.php?id=2331

题面复制于洛谷

题目描述

lxhgww的小名叫”小L“,这是因为他总是很喜欢L型的东西。小L家的客厅是一个R*C的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板。现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案?需要注意的是,如下图所示,L型地板的两端长度可以任意变化,但不能长度为0。

铺设完成后,客厅里面所有没有柱子的地方都必须铺上地板,但同一个地方不能被铺多次。

输入输出格式

输入格式:

输入的第一行包含两个整数,R和C,表示客厅的大小。接着是R行,每行C个字符。'_'表示对应的位置是空的,必须铺地板;'*'表示对应的位置有柱子,不能铺地板。

输出格式:

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

输入输出样例

输入样例#1:

2 2
*_
__
输出样例#1:

1
输入样例#2:

3 3
___
_*_
___
输出样例#2:

8

参考了:http://blog.csdn.net/regina8023/article/details/44838887

我终于可以告别插头dp啦233333……<—此人已疯

这道题的难点在于将插头dp的插头的定义进行修改。

0:无插头

1:有插头且当前格子所在的地板能再转弯。

2:有插头且当前格子所在的地板不能再转弯。

有了这些就可以按照插头dp的思想进行分情况讨论了:

(摘自参考博客)

1.00-->22 或 10 或 01

2.11-->00

3.10-->20 或 01

20-->00 或 02

4.01-->10 或 02

02-->00 或 20

最终把所有情况枚举累加即可。

PS:第二种情况的11转换成了00实质上是11相交的地方变成了这块地板的转折点(也可以理解为两块地板并在了一起)。

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int INF=;
const int mod=;
const int M=;
const int p=;
struct node{
int to,nxt;
}edge[M];
int head[M],cnt;
int n,m;
bool mp[][];
int cur,pre;
int state[][M];
ll ans[][M],cntt;
int tot[];
int bit[];
inline void getbit(){
for(int i=;i<;i++)bit[i]=i<<;
return;
}
inline void add(int u,int v){
cnt++;
edge[cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
void insert(int now,ll num){
int u=now%mod;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(state[cur][v]==now){
ans[cur][v]+=num%p;
ans[cur][v]%=p;
return;
}
}
add(u,++tot[cur]);
state[cur][tot[cur]]=now;
ans[cur][tot[cur]]=num%p;
return;
}
void plugdp(){
cur=;
tot[cur]=;
ans[cur][]=;
state[cur][]=;
for(int i=;i<=n;i++){
for(int j=;j<=tot[cur];j++){
state[cur][j]<<=;
}
for(int j=;j<=m;j++){
memset(head,,sizeof(head));cnt=;
pre=cur,cur^=;
tot[cur]=;
for(int k=;k<=tot[pre];k++){
int now=state[pre][k];
ll num=ans[pre][k]%p;
int is_down=(now>>bit[j-])%;
int is_right=(now>>bit[j])%;
if(!mp[i][j]){
if(!is_down&&!is_right)
insert(now,num);
}
else if(!is_down&&!is_right){
if(mp[i+][j])
insert(now+(<<bit[j-]),num);
if(mp[i][j+])
insert(now+(<<bit[j]),num);
if(mp[i][j+]&&mp[i+][j])
insert(now+*(<<bit[j-])+*(<<bit[j]),num);
}
else if(is_down&&!is_right){
if(is_down==){
if(mp[i+][j])insert(now+(<<bit[j-]),num);
if(mp[i][j+])insert(now-(<<bit[j-])+(<<bit[j]),num);
}else{
insert(now-*(<<bit[j-]),num);
if(mp[i][j+])insert(now-*(<<bit[j-])+*(<<bit[j]),num);
}
}
else if(!is_down&&is_right){
if(is_right==){
if(mp[i+][j])insert(now+(<<bit[j-])-(<<bit[j]),num);
if(mp[i][j+])insert(now+(<<bit[j]),num);
}else{
insert(now-*(<<bit[j]),num);
if(mp[i+][j])insert(now+*(<<bit[j-])-*(<<bit[j]),num);
}
}
else if(is_down==&&is_right==)
insert(now-(<<bit[j-])-(<<bit[j]),num);
}
}
}
for(int k=;k<=tot[cur];k++)cntt+=ans[cur][k];
return;
}
int main(){
getbit();
scanf("%d%d",&n,&m);
if(n<m){
swap(n,m);
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
char ch=getchar();
while(ch!='*'&&ch!='_')ch=getchar();
if(ch=='_')mp[j][i]=;
}
}
}else{
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
char ch=getchar();
while(ch!='*'&&ch!='_')ch=getchar();
if(ch=='_')mp[i][j]=;
}
}
}
plugdp();
printf("%lld\n",cntt);
return ;
}

BZOJ2331:[SCOI2011]地板——题解的更多相关文章

  1. bzoj2331 [SCOI2011]地板

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

  2. 【BZOJ2331】[SCOI2011]地板 插头DP

    [BZOJ2331][SCOI2011]地板 Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里 ...

  3. bzoj 2331: [SCOI2011]地板 插头DP

    2331: [SCOI2011]地板 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 541  Solved: 239[Submit][Status] D ...

  4. 【bzoj2331】[SCOI2011]地板

    题目链接: TP 题解: 分类讨论好烦啊! 0表示没有插头,1.2表示有插头,1表示接下来可以转弯,2表示接下来不能转弯,只能停在一个地方. 然后分类讨论: 插头状态 到达状态 0 0 2 2 | 1 ...

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

    [题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表 ...

  6. P3272 [SCOI2011]地板

    \(\color{#0066ff}{ 题目描述 }\) lxhgww的小名叫"小L",这是因为他总是很喜欢L型的东西.小L家的客厅是一个R*C的矩形,现在他想用L型的地板来铺满整个 ...

  7. bzoj:2331: [SCOI2011]地板

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

  8. 2331: [SCOI2011]地板 插头DP

    国际惯例的题面:十分显然的插头DP.由于R*C<=100,所以min(R,C)<=10,然后就可以愉悦地状压啦.我们用三进制状压,0表示没有插头,1表示有一个必须延伸至少一格且拐弯的插头, ...

  9. 【BZOJ】2331: [SCOI2011]地板

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2331 一眼插头DP... 考虑一个L形的东西,要构成它可以划分为两个阶段,即当前线段是拐了 ...

随机推荐

  1. [转]理解Linux文件系统之inode

    很少转发别人的文章,但是这篇写的太好了. 理解inode   作者: 阮一峰 inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础. 我觉得,理解inode,不仅有助于提高系统 ...

  2. tomcat7以上的版本,400BadRequest

    出现此原因的解决办法其一,详情可见: https://www.cnblogs.com/dygrkf/p/9088370.html. 另一种解决方法,就是把url中不允许出现的字符编码,后台接收时再解码 ...

  3. 使用Git提交与管理代码

    要成为一个合格的码农,必须要有效对自己的代码进行管理,最近打算有空就整理一下自己以前写得代码,把不涉及实验室的机密的内容等放到github上,之前只知道git clone 别人的代码,希望有一天自己的 ...

  4. Windows10 Oracle ODBC安装配置

    项目紧迫,需在短时间内交付成果,新团队成员,吐嘈之前数据库设计太low,很难看懂数据库表结构间的关系,为了使新同事更好的了解数据库表结构,特意使用powerDesigner对oracle.mysql数 ...

  5. docker简单使用+django+uwsgi+nginx项目部署

    使用docker 搭建 centos7 环境: 主机环境:windows 10专业版 一.安装docker Hub.docker.com官网下载 docker for windows 安装完成后,任务 ...

  6. ThinkPHP - 6 - 学习笔记(2015.5.4)

    解决:OneThink 站点无法被友言uyan后台识别 打开友言uyan插件功能,但OneThink站点无法被友言uyan后台检测到.页面生成的uyan代码为: <!-- UY BEGIN -- ...

  7. ab命令做压测测试

    1. 背景:互联网发达的今天,大大小小的网站如雨后春笋,不断出现,但是想要做出一个网站很简单,但是想要做好一个网站,非常非常难,首先:网站做好之后的功能怎么样这都是次要的,主要的是你的网站能承受怎么样 ...

  8. KETTLE元数据表

    表名 说明 R_CLUSTER R_CLUSTER_SLAVE R_CONDITION R_DATABASE 数据库连接信息 R_DATABASE_ATTRIBUTE 数据库属性 R_DATABASE ...

  9. Scrum立会报告+燃尽图(十一月二十五日总第三十三次):展示博客

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2413 项目地址:https://git.coding.net/zhang ...

  10. FIsherman丶Team

    小组成员:郝恒杰,洪佳兴,张子祥 组长:郝恒杰 项目:Fisher Job(渔夫兼职) 简介: 我们的产品渔夫兼职是为了解决大学生兼职群体 的痛苦,他们需要一个好的渠道去找一个让自己满意的兼职,但是现 ...