BZOJ 2331 [SCOI2011]地板 ——插头DP
【题目分析】
经典题目,插头DP。
switch 套 switch 代码瞬间清爽了。
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 400005
const int md=20110520;
int dp[2][maxn],a[101][101],n,m,fac[15],tot,b[15];
char s[105];
void print(int x){F(i,0,m) printf("%d",(x%fac[i+1])/fac[i]);}
int main()
{
scanf("%d%d",&n,&m);
F(i,0,n-1){scanf("%s",s);F(j,0,m-1)a[i][j]=s[j]=='*'?1:0;}
if (m>n){F(i,0,m-1)F(j,i+1,m-1)swap(a[i][j],a[j][i]);swap(m,n);}
// F(i,0,n-1){F(j,0,m-1)printf("%d ",a[i][j]);printf("\n");}
fac[0]=1;F(i,1,13)fac[i]=fac[i-1]*3;tot=fac[m+1]-1;
int now=1,pre=0;
memset(dp[now],0,sizeof dp[now]);
dp[now][0]=1;
F(i,0,n-1) F(j,0,m-1)
{ if (a[i][j])
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("now is "); print(s); printf(" \n");
int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
if (!tmp1&&!tmp2)
{
(dp[now][s]+=dp[pre][s])%=md;
// printf(" to "); print(s); printf("\n");
}
}
}
else
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("now is "); print(s); printf(" \n");
int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
switch(tmp1)
{
case 0:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]+2*fac[j+1]); printf("\n");
(dp[now][tmp+2*fac[j]+2*fac[j+1]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j]); printf("\n");
(dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j+1]); printf("\n");
(dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
break;
case 1:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+fac[j]); printf("\n");
(dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+2*fac[j+1]); printf("\n");
(dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
break;
case 2:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
break;
}
break;
case 1:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp+fac[j+1]); printf("\n");
(dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
break;
case 1:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
break;
case 2:
break;
}
break;
case 2:
switch(tmp2)
{
case 0:
tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
// printf(" to "); print(tmp+2*fac[j]); printf("\n");
(dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
// printf(" to "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
break;
case 1:
break;
case 2:
break;
}
break;
}
}
}
if (j==m-1)
{
// printf("On The last of road\n");
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,tot) if (dp[pre][s])
{
// printf("End with "); print(s);
int tmp=s,tmp1=(s%fac[m+1])/fac[m];
if (tmp1) {continue;}
tmp*=3;
// printf(" can become "); print(tmp); printf("\n");
(dp[now][tmp]+=dp[pre][s])%=md;
}
}
}
printf("%d\n",dp[now][0]);
}
BZOJ 2331 [SCOI2011]地板 ——插头DP的更多相关文章
- bzoj 2331: [SCOI2011]地板 插头DP
2331: [SCOI2011]地板 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 541 Solved: 239[Submit][Status] D ...
- 【BZOJ】2331: [SCOI2011]地板 插头DP
[题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表 ...
- 2331: [SCOI2011]地板 插头DP
国际惯例的题面:十分显然的插头DP.由于R*C<=100,所以min(R,C)<=10,然后就可以愉悦地状压啦.我们用三进制状压,0表示没有插头,1表示有一个必须延伸至少一格且拐弯的插头, ...
- 【BZOJ2331】[SCOI2011]地板 插头DP
[BZOJ2331][SCOI2011]地板 Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里 ...
- bzoj:2331: [SCOI2011]地板
Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板.现在小L想知道,用 ...
- bzoj 2331: [SCOI2011]地板【插头dp】
一开始设计了四种状态,多了一种已经拐弯但是长度为0的情况,后来发现不用,设012表示没插头,没拐弯的插头,拐了弯的插头,然后转移的话12,21,22都不合法,剩下的转移脑补一下即可,ans只能在11, ...
- 【BZOJ】2331: [SCOI2011]地板
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2331 一眼插头DP... 考虑一个L形的东西,要构成它可以划分为两个阶段,即当前线段是拐了 ...
- [SCOI2011][bzoj2331] 地板 [插头dp]
题面: 传送门 思路: 插头dp基础教程 这个L形......第一眼看上去真的是丧病啊 但是仔细想想,实际上也就是拿一堆路径铺满一个棋盘,这个路径还是有限制的 那还有什么好说的,插头dp上啊[雾] 首 ...
- BZOJ.1210.[HNOI2004]邮递员(插头DP Hash 高精)
BZOJ 洛谷 http://www.cnblogs.com/LadyLex/p/7326874.html 插头DP.\(m+1\)个插头的状态需要用三进制表示:\(0\)表示无插头,\(1\)表示是 ...
随机推荐
- Android - Zxing实现二维码的扫描与生成
Zxing: Zxing是一个开放源码,用java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口.可以实现使用手机内置摄像头完成条形码的扫描以及解码. github: ...
- 倒计时器 CountDownTimer
使用介绍 开发中经常会遇到一些和倒计时有关的场景,比如发送验证码的按钮,会在点击发送后,显示倒计时间,倒计时结束后才能够刷新按钮,再次允许点击.为了不阻塞软件的运行,又要实时刷新界面,我们通常会用到 ...
- /etc/default/useradd
系统默认的shell在,/etc/default/useradd 中,添加用户的时候如果不指定shell,默认的shell就是该文件下制定的文件
- Node.js 打造实时多人游戏框架
在 Node.js 如火如荼发展的今天,我们已经可以用它来做各种各样的事情.前段时间UP主参加了极客松活动,在这次活动中我们意在做出一款让“低头族”能够更多交流的游戏,核心功能便是 Lan Party ...
- 并查集+思维——Destroying Array
一.题目描述(题目链接) 给定一个序列,按指定的顺序逐一删掉,求连续子序列和的最大值.例如序列1 3 2 5,按3 4 1 2的顺序删除,即依次删除第3个.第4个.第1个.第2个,答案为5 4 3 0 ...
- Python学习笔记3(字典)
创建字典 dict函数 字典的格式化字符串 字典方法 clear copy fromkeys 序列是一个按照一定顺序将值进行组织的数据结构形式,可以通过索引对其进行征引.另外还有一种数据结构是通过名字 ...
- Fortran学习笔记4(循环语句)
Fortran学习笔记4 Fortran学习笔记4 逻辑运算 循环 Do语句 Do-While循环 循环控制 循环应用实例 逻辑运算 if命令需要和逻辑运算表达式搭配才能起到很好的效果.下面分别列出F ...
- LeetCode 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 ...
- ELK踩过的各种坑 6.4版本
一.elasticsearch 1.服务正常启动,但不能正常访问 [root@linux-node1 elasticsearch]# systemctl start elasticsearch [ro ...
- python数据类型、字符编码、文件处理
介绍: 1.什么是数据? 例:x=10,10是我们要存储的数据 2.为何数据要分不同的类型? 数据是用来表示状态的,不同的状态用不同的类型的数据去表示 1.数据类型 1.数字(整形,长整形,浮点型,复 ...