题面:

传送门

思路:

插头dp基础教程

这个L形......第一眼看上去真的是丧病啊

但是仔细想想,实际上也就是拿一堆路径铺满一个棋盘,这个路径还是有限制的

那还有什么好说的,插头dp上啊【雾】

首先。我们定义这道题中的一个插头代表着从这个格子往插头指向的方向可以伸展一个L形

但是整张图上的所有插头不可能只有一种,因此我们要分析,可以继续延伸的L形都有哪些限制呢?

我们知道,L形的一个特点就是拐了一个弯,而且只拐了一个弯,因此我们可以定义这样的两种插头:

插头1代表一个还没有拐过弯的L形的延伸,插头2则代表一个已经拐过弯的L形的延伸

这样我们解决了定义问题,接下来看如何分类讨论

第一种情况:当前状态下,当前格子上方和左方都没有插头

这时我们需要找一个L形来把这个格子填上,那么我们可能有三种决策:

  决策一:给这个格子加一个二号下插头和一个二号右插头,此时这个格子是一个新的L形的拐角

  决策二:给这个格子加一个一号下插头,此时相当于构建了一个先向下再向右的L形,从当前格子开始

  决策三:给这个格子加一个一号右插头,此时相当于构建了一个先向右再向下的L形,从当前格子开始

第二种情况:当前状态下,当前格子上方有一个一号下插头,左方没有插头

这时相当于上面有一个L形的未拐弯的一边伸过来了,有两种决策:

  决策一:L形不拐弯,继续向下延伸,当前格子只有一个一号下插头

  决策二:L形在当前格子拐弯,L形向右延伸,当前格子只有一个二号右插头

第三种情况:当前状态下,当前格子左方有一个一号右插头,上方没有插头

与第二种情况类似,故不赘述

第四种情况:当前状态下,当前格子上方有一个二号下插头,左方没有插头

这时相当于上面有一个L形的拐过弯的一边伸过来了,有两种决策:

  决策一:L形继续延伸,当前格子有一个二号下插头

  决策二:L形在当前格子终止,当前格子没有插头

决策二时注意,如果当前处在最后一个没有障碍的格子,那么需要统计入最终答案

第五种情况:当前状态下,当前格子左方有一个二号右插头,上方没有插头

与第四种情况类似,故不赘述

第六种情况:当前状态下,当前格子左方和上方都有一号插头

此时相当于两条“臂”伸了过来,在当前格子相交,应该合并成一个L形

当前格子相当于一个L形的拐弯处,没有插头

我们发现,情况一和情况六已经覆盖了四种L形的摆放方式,同时也不会有一个二号插头一个一号插头或者两个二号插头的情况出现——它们被上文的六种情况限制了

故这种分类讨论方式可以覆盖所有情况

状态可以用四进制表示(比较快),因为状态数较多,放到哈希表里面,滚动数组处理即可

Code:

 // luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define hash deep_dark_fantasy
#define ll long long
#define MOD 20110520
using namespace std;
inline int read(){
int re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
int n,m,x[][],cur,pre,ex,ey;
int st[][];ll ans[][],re;
int tot[],bit[],state[],st_tot,hash=;
struct edge{
int to,next;
}a[];
void insert(int now,ll val){
int p=now%hash;
for(int i=state[p];i;i=a[i].next){
if(st[cur][a[i].to]==now){
ans[cur][a[i].to]+=val;
ans[cur][a[i].to]%=MOD;return;
}
}
tot[cur]++;
a[++st_tot].to=tot[cur];
a[st_tot].next=state[p];
state[p]=st_tot;st[cur][tot[cur]]=now;ans[cur][tot[cur]]=val%MOD;
}
void dp(){
int i,j,k,down,right,now;ll val;
cur=;tot[cur]=;ans[cur][]=;st[cur][]=;
for(i=;i<=n;i++){
for(j=;j<=tot[cur];j++) st[cur][j]<<=;
for(j=;j<=m;j++){
memset(state,,sizeof(state));st_tot=;
pre=cur;cur^=;tot[cur]=;
for(k=;k<=tot[pre];k++){
now=st[pre][k];val=ans[pre][k];
right=(now>>bit[j-])%;down=(now>>bit[j])%;
if(!x[i][j]){//障碍格子
if(!down&&!right){
insert(now,val);continue;
}
}
if(!right&&!down){//第一种情况
if(x[i+][j]&&x[i][j+])
insert(now+((<<bit[j-])<<)+((<<bit[j])<<),val);
if(x[i+][j]) insert(now+(<<bit[j-]),val);
if(x[i][j+]) insert(now+(<<bit[j]),val);
}
if(right==&&!down){//第三种情况
if(x[i][j+]) insert(now-(<<bit[j-])+(<<bit[j]),val);
if(x[i+][j]) insert(now+(<<bit[j-]),val);
}
if(down==&&!right){//第二种情况
if(x[i+][j]) insert(now-(<<bit[j])+(<<bit[j-]),val);
if(x[i][j+]) insert(now+(<<bit[j]),val);
}
if(right==&&!down){//第五种情况
if(i==ex&&j==ey) re+=val,re%=MOD;
if(x[i][j+]) insert(now-((<<bit[j-])<<)+((<<bit[j])<<),val);
insert(now-((<<bit[j-])<<),val);
}
if(down==&&!right){//第四种情况
if(i==ex&&j==ey) re+=val,re%=MOD;
if(x[i+][j]) insert(now-((<<bit[j])<<)+((<<bit[j-])<<),val);
insert(now-((<<bit[j])<<),val);
}
if(down==&&right==){//第六种情况
if(i==ex&&j==ey) re+=val,re%=MOD;
insert(now-(<<bit[j-])-(<<bit[j]),val);
}
}
}
}
}
int main(){
int i,j;char ch;
n=read();m=read();
for(i=;i<=;i++) bit[i]=i<<;
if(n>m){
for(i=;i<=n;i++){
for(j=;j<=m;j++){
ch=getchar();
while(ch!='*'&&ch!='_') ch=getchar();
x[i][j]=(ch=='_');
if(x[i][j]) ex=i,ey=j;
}
}
}
else{
swap(n,m);
for(i=m;i>;i--){
for(j=;j<=n;j++){
ch=getchar();
while(ch!='*'&&ch!='_') ch=getchar();
x[j][i]=(ch=='_');
if(x[j][i]&&((j>ex)||(j==ex&&i>ey))) ex=j,ey=i;
}
}
}
dp();
printf("%lld",re);
}

[SCOI2011][bzoj2331] 地板 [插头dp]的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. [BZOJ2331]地板(插头DP)

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

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

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

  8. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...

  9. 插头dp初探

    问题描述 插头dp用于解决一类可基于图连通性递推的问题.用插头来表示轮廓线上的连通性,然后根据连通性与下一位结合讨论进行转移. 表示连通性的方法 与字符串循环最小表示不同,这种方法用于给轮廓线上的联通 ...

随机推荐

  1. 关于C#的垃圾回收机制,Finalize和Dispose的区别(自认为很清晰了,有疑问的评论)

    来到个新地方,新学习C#,前面看到C#的垃圾回收,Finalize和Dispose时,总是一知半解,迷迷糊糊.这次好了,前面连续两次面试问到这个问题,脑子里不是很清晰,加上用英文来表达,更是雪上加霜的 ...

  2. FreeRTOS_软件定时器

    FreeRTOS 软件定时器 实验 创建2个任务,start_task.timercontrol_task. start_stask:创建timercontrol_task任务:创建周期定时器Auto ...

  3. Docker学习笔记--2 镜像的创建

    如果我们需要在Docker环境下部署tomcat.redis.mysql.nginx.php等应用服务环境,有下面三种方法: 1,根据系统镜像创建Docker容器,这时容器就相当于是一个虚拟机,进入容 ...

  4. 怎样查看web软件例如apache的连接数

    查看连接总数和当前的连接数 netstat -ant | grep $ip:80 | wc -l netstat -ant | grep $ip:80 | grep EST | wc -l 查看IP访 ...

  5. IP代理池之验证是否有效

    IP代理池之验证是否有效 把proxy pool项目跑起来,但也不知道这些ip怎么用,爬虫的时候是否用代理去爬取,下面通过一个例子来看看. 代码如下: import requests PROXY_PO ...

  6. 动态规划:最长上升子序列(二分算法 nlogn)

    解题心得: 1.在数据量比较大的时候n^2会明显超时,所以可以使用nlogn 的算法,此算法少了双重循环,用的lower_bound(二分法). 2.lis中的数字并没有意义,仅仅是找到最小点lis[ ...

  7. hive实现根据用户分组,按用户记录求上下两条记录的时间差

    在mysql,数据如下:#查询某一用户该日抽奖时间 select draw_time from user_draw_log where user_id = 1 and draw_date='2016- ...

  8. Altium Designer

    抗干扰设计原则: 1.电源线的设计 选择合适的电源 尽量加宽电源线 保证电源线.底线走向和数据传输方向一致 使用抗干扰元器件(磁珠.电源滤波器等) 电源入口添加去耦电容 2.底线的设计 模拟地和数字地 ...

  9. 消息框模块-tkinter

    import tkinter.messagebox # 这个是消息框,对话框的关键from tkinter import * error_fp_list = [[973.45, '河北卡卡汽车贸易有限 ...

  10. 回顾Scrum学习:《Scrum实战》第4次课【全职的Scrum Master】作业

    回顾Scrum学习   1.回顾目标 1.1 期望结果 了解和学习Scrum,为将来换方向打好理论基础 如果能在目前公司引入和推行也很好,但是根据目前公司的文化氛围来看,推行希望不大 把敏捷思想应用到 ...