传送门

感谢大佬的教导->这里

容易注意到,本题的合法路径“L型地板”有一些特殊的地方:拐弯且仅拐弯一次。

这由于一条路径只有两种状态:拐弯过和没拐弯过,因此我们可以尝试着这样定义新的插头:

我们使用三进制,0代表没有插头,1代表没拐弯过的路径,2代表已经拐弯过的路径。

依然设当前转移到格子(x,y),设y-1号插头状态为p1,y号插头状态为p2。

那么会有下面的几种情况:

  情况1:p1==0&&p2==0

    这时我们有三种可选的策略:

      ①以当前位置为起点,从p1方向引出一条新的路径(把p1修改为1号插头)

      ②以当前位置为起点,从p2方向引出一条新的路径(把p2修改为1号插头)

      ③以当前位置为“L”型路径的转折点,向p1,p2两个方向均引出一个2号插头.

  情况2:p1==0&&p2==1

    由于p2节点还没有拐过弯,因此我们有2种可选的策略:

      ①继续直走,不拐弯,即上->下(把p1修改为1号插头,p2置0)

      ②选择拐弯,即上->右(把p2改为2号插头)

  情况3:p1==1&&p2==0

    这种情况和情况2类似

  情况4:p1==0&&p2==2

    由于p2节点已经拐过弯,所以我们有如下的两种策略:

    ①路径在此停止。那么我们以本格作为L型路径的一个端点。如果当前处于最后一个非障碍格子,如果没有其他的插头,我们此时就可以统计答案了。
    ②路径延续。由于p2已经转弯过,因此我们只能选择继续直走,即上->下(把p1修改为2号插头,p2置0)和之前相似的方法把独立插头传递下去即可。

  情况5:p1==2&&p2==0

    这种情况与情况4类似

  情况6:p1==1&&p2==1

    这种情况下,两块地板均没有拐过弯,因此我们可以在本格将这两块地板合并,形成一个合法的“L”型路径,并将本格看做他们的转折点。(把p1和p2都置为0)

至此,新插头定义的状态转移已经讨论完成。

不难发现,这种新的插头定义可以处理可能发生的所有可行情况。

然后上代码

 //minamoto
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,HASH=,mod=;
int ans,n,m,lastx,lasty;char c[N][N];bool room[N][N];
struct node{
int val[HASH],key[HASH],Hash[HASH],sz;
inline void init(){
memset(val,,sizeof(val)),memset(Hash,,sizeof(Hash));
memset(key,-,sizeof(key)),sz=;
}
inline void newhash(int id,int state){Hash[id]=++sz,key[sz]=state;}
inline int &operator [](const int state){
for(int i=state%HASH;;i=(i+==HASH)?:i+){
if(!Hash[i]) newhash(i,state);
if(key[Hash[i]]==state) return val[Hash[i]];
}
}
}f[];
inline int find(int state,int pos){return (state>>((pos-)<<))&;}
inline void set(int &state,int pos,int val){
pos=(pos-)<<,state|=<<pos,state^=<<pos,state^=val<<pos;
}
void solve(int x,int y){
int now=((x-)*m+y)&,last=now^,tot=f[last].sz;
f[now].init();
for(int i=;i<=tot;++i){
int state=f[last].key[i],val=f[last].val[i];
int plug1=find(state,y),plug2=find(state,y+);
if(!room[x][y]){
if(!plug1&&!plug2) (f[now][state]+=val)%=mod;
}
else{
if(!plug1&&!plug2){
if(room[x+][y]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(room[x][y+]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(room[x][y+]&&room[x+][y]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
}
else if(!plug1&&plug2){
if(plug2==){
if(room[x+][y]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(room[x][y+]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
}
else{
set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(x==lastx&&y==lasty&&!state) (ans+=val)%=mod;
if(room[x+][y]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
}
}
else if(plug1&&!plug2){
if(plug1==){
if(room[x][y+]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(room[x+][y]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
}
else{
set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(x==lastx&&y==lasty&&!state) (ans+=val)%=mod;
if(room[x][y+]) set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
}
}
else if(plug1==&&plug2==){
set(state,y,),set(state,y+,),(f[now][state]+=val)%=mod;
if(x==lastx&&y==lasty&&!state)(ans+=val)%=mod;
}
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i) scanf("%s",c[i]+);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
room[i][j]=(c[i][j]=='_');
if(m>n){
for(int i=;i<=n;++i)
for(int j=i+;j<=m;++j)
swap(room[i][j],room[j][i]);
swap(n,m);
}
int flag=;
for(int i=n;i&&flag;--i)
for(int j=m;j&&flag;--j)
if(room[i][j]){lastx=i,lasty=j;flag=;}
f[].init(),f[][]=;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j) solve(i,j);
if(i!=n)
for(int j=,last=(i*m)&,tot=f[last].sz;j<=tot;++j)
f[last].key[j]<<=;
}
printf("%d\n",ans);
return ;
}

洛谷P3272 [SCOI2011]地板(插头dp)的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ 2331 [SCOI2011]地板 ——插头DP

    [题目分析] 经典题目,插头DP. switch 套 switch 代码瞬间清爽了. [代码] #include <cstdio> #include <cstring> #in ...

  6. 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)

    洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\)​​​​​.我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...

  7. P3272 [SCOI2011]地板(插头DP)

    [题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...

  8. [SCOI2011][bzoj2331] 地板 [插头dp]

    题面: 传送门 思路: 插头dp基础教程 这个L形......第一眼看上去真的是丧病啊 但是仔细想想,实际上也就是拿一堆路径铺满一个棋盘,这个路径还是有限制的 那还有什么好说的,插头dp上啊[雾] 首 ...

  9. 洛谷2344 奶牛抗议(DP+BIT+离散化)

    洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...

随机推荐

  1. Java for LeetCode 125 Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  2. CodeChef - ANDMIN —— 线段树 (结点最多被修改的次数)

    题目链接:https://vjudge.net/problem/CodeChef-ANDMIN Read problems statements in Mandarin Chinese, Russia ...

  3. 浅析android中的依赖注入

    这几年针对Android推出了不少View注入框架,例如ButterKnife.我们首先来了解一下使用这些框架有什么好处,其实好处很明显:它可以减少大量的findViewById以及setOnClic ...

  4. javascript(5)

    (1)数组的细节: 基本用法 var 数组名=[元素值,元素值...]; 元素的值可以是任意类型. 数组是引用类型. js里的引用. 在函数参数列表中,如果传入的是基本类型,那 按值传递.如果传入的是 ...

  5. html5--2.6新的布局元素(5)-nav

    html5--2.6新的布局元素(4)-aside/nav 学习要点 了解aside/nav元素的语义和用法 通过实例理解aside/nav元素的用法 aside元素 aside元素通常用来设置侧边栏 ...

  6. wingide 显示中文 及 配色方案

    http://lihuipeng.blog.51cto.com/3064864/923231 网上收集的方法: 显示中文: 任意文本编辑器打开:x:\Wing IDE\bin\gtk-bin\etc\ ...

  7. Python实现排序算法之快速排序

    Python实现排序算法:快速排序.冒泡排序.插入排序.选择排序.堆排序.归并排序和希尔排序 Python实现快速排序 原理 首先选取任意一个数据(通常选取数组的第一个数)作为关键数据,然后将所有比它 ...

  8. Codeforces Round #397 题解

    Problem A. Neverending competitions 题目大意 一个团队有多个比赛,每次去比赛都会先订机票去比赛地点,然后再订机票返回.给出\(n\)个含有起止地点的购票记录(不按时 ...

  9. bzoj 3527: [Zjoi2014]力 快速傅里叶变换 FFT

    题目大意: 给出n个数\(q_i\)定义 \[f_i = \sum_{i<j}{\frac{q_iq_j}{(i-j)^2}} - \sum_{i>j}\frac{q_iq_j}{(i-j ...

  10. 洛谷 P2919 [USACO08NOV]守护农场Guarding the Farm

    题目描述 The farm has many hills upon which Farmer John would like to place guards to ensure the safety ...