【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>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=,MM=,MOD=,S=;
int map[maxn][maxn],n,m,c[maxn];
int M(int x){return x>=MM?x-MM:x;}
struct h{
int state[S],ans[S],first[MOD],tot,nxt[S];
void init(){
memset(first,,sizeof(first));
tot=;
}
void insert(int x,int num){
for(int i=first[x%MOD];i;i=nxt[i])if(state[i]==x){
ans[i]=M(ans[i]+num);
return;
}
state[++tot]=x;ans[tot]=num;
nxt[tot]=first[x%MOD];first[x%MOD]=tot;
}
}f[];
void decode(int x){for(int i=m;i>=;i--)c[i]=x&,x>>=;}
int encode(){int x=;for(int i=;i<=m;i++)x=(x<<)|c[i];return x;}
void solve(int cur,int x,int y){
for(int k=;k<=f[cur^].tot;k++){
decode(f[cur^].state[k]);
int ans=f[cur^].ans[k],left=c[y-],up=c[y];
if(left==){
if(up==){
if(map[x][y+]&&map[x+][y]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
if(map[x+][y]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
if(map[x][y+]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
}
if(up==){
if(map[x+][y]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
if(map[x][y+]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
}
if(up==){
if(map[x+][y]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
}
if(left==){
if(up==){
if(map[x+][y]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
if(map[x][y+]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
}
if(up==){
c[y-]=c[y]=;
f[cur].insert(encode(),ans);
}
}
if(left==){
if(up==){
if(map[x][y+]){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
}
}
}
char s[maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=m;j++)if(s[j]=='_'){
if(m<=)map[i][j]=;else map[j][i]=;
}
}
if(m>)swap(n,m);
int cur=;f[].init();f[].insert(,);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++)if(map[i][j]){
f[cur^=].init(),solve(cur,i,j);
}
for(int j=;j<=f[cur].tot;j++)f[cur].state[j]>>=;
}
int ans=;
for(int i=;i<=f[cur].tot;i++)ans=M(ans+f[cur].ans[i]);
printf("%d",ans);
return ;
}
经历:开始看错题,以为是向右向下延伸的方块,就1表示可以延伸的插头,2表示必须延伸的插头。
但其实这也是不必要的,插头DP通常强制限定插头指向的方块必须选择,而在之前插的时候提前判断是否能选。
【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
[题目分析] 经典题目,插头DP. switch 套 switch 代码瞬间清爽了. [代码] #include <cstdio> #include <cstring> #in ...
- 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\)表示是 ...
随机推荐
- Java中按值传递与按引用传递的区别
值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...
- 如何利用Xshell在Linux下安装jdk
本文会详细介绍如何在Linux下安装JDK1.8 首先要设置虚拟机的IP地址,不知道如何设置的话可以 翻看我的前一篇博客 http://www.cnblogs.com/xiaoxiaoSMILE/ ...
- 01_Java基础_第1天(Java概述、环境变量、注释、关键字、标识符、常量)_讲义
今日内容介绍 1.Java开发环境搭建 2.HelloWorld案例 3.注释.关键字.标识符 4.数据(数据类型.常量) 01java语言概述 * A: java语言概述 * a: Java是sun ...
- OSG学习:阴影代码示例
效果图: 代码示例: #include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geode> #i ...
- 第145天:jQuery.touchSlider触屏满屏左右滚动幻灯片
1.HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...
- HDU4810_Wall Painting
题目很简单. 给你n个数,输出n个答案,第i个答案表示从n个数里取遍i个数的异或值的和. 其实每一个数最多也就32位,把所有的数分解,保存每一位总共有多少个1,最后要是这一位的异或结果为1,那么在所有 ...
- BZOJ 2957 楼房重建(线段树区间合并)
一个显而易见的结论是,这种数字的值是单调递增的.我们修改一个数只会对这个数后面的数造成影响.考虑线段树划分出来的若干线段. 这里有两种情况: 1.某个线段中的最大值小于等于修改的数,那么这个线段的贡献 ...
- Toast与Snackbar的那点事
背景 Toast是Android平台上的常用技术.从用户角度来看,Toast是用户与App交互最基本的提示控件:从开发者角度来看,Toast是开发过程中常用的调试手段之一.此外,Toast语法也非常简 ...
- BZOJ2743:[HEOI2012]采花——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2743 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建 ...
- NOI2013 矩阵游戏 【数论】
题目描述 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i ...