题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2331


一眼插头DP...

考虑一个L形的东西,要构成它可以划分为两个阶段,即当前线段是拐了弯的还是没有拐弯的。
所以$4$进制表示,$0$表示没有插头,$1$表示插头指向拐点,$2$表示插头离开拐点。

转移:

令${(x,y)}$表示当前点左插头和上插头的形态。

${(0,0)}$------>${(0,1)}$,${(1,0)}$,${(2,2)}$

${(0,1)}$------>${(1,0)}$,${(0,2)}$

${(0,2)}$------>${(0,0)}$,${(2,0)}$

${(1,0)}$------>${(0,1)}$,${(2,0)}$

${(2,0)}$------>${(0,0)}$,${(0,2)}$

当然如果有障碍就不能走。


 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 10010
#define llg long long
#define SIZE 10007
#define md 20110520
#define maxnZT (1<<21)
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,code[maxn],zt[][maxnZT],v[][maxnZT],g[][],size[],now,la; struct node
{
llg pos,x,val;
}; vector<node>a[][SIZE]; void outcode(llg x){for (llg i=;i<=m;i++) code[i]=x&,x>>=;} void encode(llg p,llg val)
{
llg x=;
for (llg i=;i<=m;i++) x+=code[i]*(<<(i*));
llg wz=x%SIZE,E=a[p][wz].size();
for (llg i=;i<E;i++)
if (a[p][wz][i].x==x)
{
a[p][wz][i].val+=val; a[p][wz][i].val%=md;
v[p][a[p][wz][i].pos]+=val; v[p][a[p][wz][i].pos]%=md;
return ;
}
size[p]++;
node NEW;
NEW.pos=size[p],NEW.x=x,NEW.val=val;
a[p][wz].push_back(NEW);
zt[p][size[p]]=x; v[p][size[p]]=val;
} void init()
{
cin>>n>>m;
char ch;
for (llg i=;i<=n;i++)
for (llg j=;j<=m;j++)
{
ch=getchar();
while (ch!='*' && ch!='_') ch=getchar();
if (n<m) g[j][i]=(ch=='_');
else g[i][j]=(ch=='_');
}
if (n<m) swap(n,m);
} void init_a(llg p){for (llg i=;i<SIZE;i++) a[p][i].clear(); size[p]=;} void DP()
{
llg le,up,V;
encode(,);
for (llg i=;i<=n;i++)
{
for (llg k=;k<=size[now];k++) zt[now][k]*=;//轮廓线左移一格
for (llg j=;j<=m;j++)
{
now^=; la=now^; size[now]=;
init_a(now);
for (llg k=;k<=size[la];k++)
{
outcode(zt[la][k]);
le=code[j-],up=code[j],V=v[la][k];//提取左插头和上插头 if (g[i][j]==)
{
if (le== && up==) encode(now,V);
continue;
} if (!le && !up)
{
if (j<m && g[i][j+]==)
{
code[j-]=,code[j]=;
encode(now,V);
if (g[i+][j]==)
{
code[j-]=code[j]=;
encode(now,V);
}
}
if (g[i+][j]==)
{
code[j-]=,code[j]=;
encode(now,V);
}
continue;
} if (le && up)
{
if (le== && up==)
{
code[j-]=code[j]=;
encode(now,V);
}
continue;
} if (le== && up==)
{
if (g[i+][j]==)
{
code[j-]=;
encode(now,V);
}
if (g[i][j+]== && j<m)
{
code[j]=; code[j-]=;
encode(now,V);
}
continue;
} if (le== && up==)
{
if (j<m && g[i][j+]==)
{
code[j]=; code[j-]=;
encode(now,V);
}
code[j]=code[j-]=;
encode(now,V);
continue;
} if (le== && up==)
{
if (g[i+][j]==)
{
code[j-]=,code[j]=;
encode(now,V);
}
if (j<m && g[i][j+]==)
{
code[j-]=; code[j]=;
encode(now,V);
}
continue;
} if (le== && up==)
{
if (g[i+][j]==)
{
code[j]=,code[j-]=;
encode(now,V);
}
code[j-]=code[j]=;
encode(now,V);
continue;
}
}
}
}
} int main()
{
yyj("BZOJ2331");
init();
DP();
llg ans=;
bool pd;
for (llg i=;i<=size[now];i++)
{
outcode(zt[now][i]);
pd=true;
for (llg j=;j<=m;j++) if (code[j]) pd=false;
if (pd) ans+=v[now][i];
}
cout<<ans%md;
return ;
}

【BZOJ】2331: [SCOI2011]地板的更多相关文章

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

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

  2. bzoj:2331: [SCOI2011]地板

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

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

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

  4. bzoj 2331: [SCOI2011]地板【插头dp】

    一开始设计了四种状态,多了一种已经拐弯但是长度为0的情况,后来发现不用,设012表示没插头,没拐弯的插头,拐了弯的插头,然后转移的话12,21,22都不合法,剩下的转移脑补一下即可,ans只能在11, ...

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

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

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

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

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

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

  8. BZOJ 2331 地板

    妈妈我会写插头dp了!!!!!!.... 感动啊... #include<iostream> #include<cstdio> #include<cstring> ...

  9. BZOJ2331:[SCOI2011]地板——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2331 题面复制于洛谷 题目描述 lxhgww的小名叫”小L“,这是因为他总是很喜欢L型的东西.小L家 ...

随机推荐

  1. qt 提高图片加载速度

    一,将图片在pc上解析,然后将解析文件放到qrc文件中,读取qrc文件. 1,将图片解析后的二进制文件保存,源码如下, 下载地址:https://files.cnblogs.com/files/sen ...

  2. Python+OpenCV图像处理(九)—— 模板匹配

    百度百科:模板匹配是一种最原始.最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题.它是图像处理中最基本.最常用的匹配方法.模板匹配具有自身的局限性, ...

  3. ubunta_django_install

    sudo apt-get install python-pip sudo apt-get install python-virtualenv #安装本地虚拟环境管理工具 mkdir ~/django ...

  4. 八大排序算法之七—堆排序(Heap Sort)

    堆排序是一种树形选择排序,是对直接选择排序的有效改进. 基本思想: 堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足 时称之为堆.由堆的定义可以看出,堆顶元素(即第一个元素) ...

  5. puts函数

    1.puts函数是gets函数的输出版本,它把指定的字符串写到标准输出并在末尾添加一个换行符 #include <stdio.h> #include <stdlib.h> in ...

  6. ES6知识整理(3)--函数的扩展

    只有整理过的学习才是有效的学习.也就是学习之后要使用和整理成文,才是真正的学到了... 最近上班有点忙的关系,于是文章更新会慢些.只有晚上加完班之后,空余时间才能学习整理.因此完成一篇也可能要几个晚上 ...

  7. Linux中USB协议栈的框架简介

    文本旨在简单介绍一下Linux中USB协议栈的代码框架: 下图是USB协议栈相关数据结构的关系图: 下面结合上图看一下系统初始化的流程: 1.USB子系统初始化:\drivers\usb\core\u ...

  8. HTML <​canvas> testing with Selenium and OpenCV

    from: https://www.linkedin.com/pulse/html-canvas-testing-selenium-opencv-maciej-kusz Since HTML < ...

  9. Strom学习笔记2:Storm Maven Project-StromStack工程

    1:IntelliJ新建Maven工程

  10. udp丢包 处理

    转自: 自己在做UDP传输时遇到的问题,接收端没设置缓存,结果总是丢包. 看到这篇文章设置了一下接收缓存就好 *;//设置为32K setsockopt(s,SOL_SOCKET,SO_RCVBUF, ...