P5056-[模板]插头dp
正题
题目链接:https://www.luogu.com.cn/problem/P5056
题目大意
\(n*m\)的网格,求有多少条回路可以铺满整个棋盘。
解题思路
插头\(dp\)的,写法是按照题解上的写法。
状态用的是括号匹配,然后用了哈希+邻接表(挂表)还有滚动数组优化空间
然后可以看题解学
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int P=133331;
struct node{
int to,next;
}a[P*2];
int n,m,o,tot,zx,zy,t[2],bit[25],ls[P],S[2][P],v[25][25];
long long ans,dp[2][P];
char st[25];
void Add(int s,long long v){
int x=s%P;
for(int i=ls[x];i;i=a[i].next)
if(S[o][a[i].to]==s)
{dp[o][a[i].to]+=v;return;}
t[o]++;dp[o][t[o]]=v;S[o][t[o]]=s;
a[++tot].to=t[o];a[tot].next=ls[x];ls[x]=tot;
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",st+1);
for(int j=1;j<=m;j++)
if(st[j]=='.'){v[i][j]=1;zx=i;zy=j;}
}
for(int i=0;i<=12;i++)bit[i]=(1<<(i<<1));
t[o]=1;S[o][1]=0;dp[o][1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=t[o];j++)S[o][j]<<=2;//将右插头移到最左边
for(int j=1;j<=m;j++){
o^=1;tot=t[o]=0;
memset(ls,0,sizeof(ls));
int s,dpl,rpl;long long w;
for(int k=1;k<=t[!o];k++){
s=S[!o][k];w=dp[!o][k];
dpl=(s>>(j<<1))%4;
rpl=(s>>(j-1<<1))%4;
if(!v[i][j]){//障碍
if(!dpl && !rpl)Add(s,w);//不能有插头
}
else if(!dpl && !rpl){//两边都没有插头
if(v[i+1][j]&&v[i][j+1])//开一个左上角插头
Add(s+2*bit[j]+bit[j-1],w);
}
else if(!dpl && rpl){//只有右插头
if(v[i+1][j])Add(s,w);
if(v[i][j+1])Add(s-rpl*bit[j-1]+rpl*bit[j],w);
}
else if(dpl && !rpl){//只有下插头
if(v[i+1][j])Add(s-dpl*bit[j]+dpl*bit[j-1],w);
if(v[i][j+1])Add(s,w);
}
else if(dpl==1&&rpl==1){
int c=1;
for(int p=j+1;p<=m;p++){
if((s>>(p<<1))%4==1)c++;
if((s>>(p<<1))%4==2)c--;
if(!c){Add(s-bit[j]-bit[j-1]-bit[p],w);break;}
}
}
else if(dpl==2&&rpl==2){
int c=1;
for(int p=j-2;p>=0;p--){
if((s>>(p<<1))%4==2)c++;
if((s>>(p<<1))%4==1)c--;
if(!c){Add(s-2*bit[j]-2*bit[j-1]+bit[p],w);break;}
}
}
else if(dpl==1&&rpl==2)
Add(s-2*bit[j-1]-bit[j],w);
else if(dpl==2&&rpl==1)
if(i==zx&&j==zy)ans+=w;
}
}
}
printf("%lld\n",ans);
return 0;
}
P5056-[模板]插头dp的更多相关文章
- 模板—插头dp(Ural 1519 Formula 1)
括号表示法: 据说比下一个要快而且灵活. #include<iostream> #include<cstring> #include<cstdio> #define ...
- P5056 【模板】插头dp
\(\color{#0066ff}{ 题目描述 }\) 给出n*m的方格,有些格子不能铺线,其它格子必须铺,形成一个闭合回路.问有多少种铺法? \(\color{#0066ff}{输入格式}\) 第1 ...
- 插头DP模板
/* 插头dp模板 抄的GNAQ 的 括号表示法 */ #include<cstdio> #include<algorithm> #include<cstring> ...
- 模板:插头dp
前言: 严格来讲有关dp的都不应该叫做模板,因为dp太活了,但是一是为了整理插头dp的知识,二是插头dp有良好的套路性,所以姑且还叫做模板吧. 这里先推荐一波CDQ的论文和这篇博客http://www ...
- bzoj1814 Ural 1519 Formula 1(插头dp模板题)
1814: Ural 1519 Formula 1 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 924 Solved: 351[Submit][Sta ...
- LG5056 【模板】插头dp
题意 题目背景 ural 1519 陈丹琦<基于连通性状态压缩的动态规划问题>中的例题 题目描述 给出n*m的方格,有些格子不能铺线,其它格子必须铺,形成一个闭合回路.问有多少种铺法? 输 ...
- 【模板】插头dp
题目描述 题解: 插头$dp$中经典的回路问题. 首先了解一下插头. 一个格子,上下左右四条边对应四个插头.就像这样: 四个插头. 一个完整的哈密顿回路,经过的格子一定用且仅用了两个插头. 所以所有被 ...
- [学习笔记]插头dp
基于连通性的状压dp 巧妙之处:插头已经可以表示内部所有状态了. 就是讨论麻烦一些. 简介 转移方法:逐格转移,分类讨论 记录状态方法:最小表示法(每次要重新编号,对于一类没用“回路路径”之类的题,可 ...
- 插头dp小结
插头dp: \(A:\)插头dp是什么? \(B:\)一种基于连通性状态压缩的动态规划问题 \(A:\)请问有什么应用呢? \(B:\)各种网格覆盖问题,范围允许状压解决,常用于计算方案数与联通块权值 ...
- 插头dp
插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...
随机推荐
- C# 中的反射机制
C# 中的反射 首先我们通过两个实例来说明反射的大体概念.B超:大家体检的时候大概都做过B超,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射 ...
- C#基础知识---获取调用者信息
一.概述 C#5.0提供了一种新功能,可以利用特性和可选参数获得调用者的信息.这些特性信息包括CallerLineNumber.CallerFilePath和CallerMemberName. 二.D ...
- C#根据输入的字符串来创建类的实例
abstract class Vehicle { public abstract void Drive(); } class Car : Vehicle { public override void ...
- QT 中的模态和非模态对话框
void MainWindow::on_pushButton_clicked() { //模态 QDialog dlg(this); dlg.resize(100,100); dlg.exec(); ...
- ThreadLocal, volatile, synchronized, map, epoll, AQS简单总结
ThreadLocal ThreadLocal主要是为了解决内存泄漏的问题,它是一种弱引用: 引用总共有四种,,我简单列一下: 强引用(Strong Reference):正常引用,根据垃圾回收算法, ...
- Go: 复合数据类型struct
结构体 结构体是将零个或多个任意类型的命名变量组合在一起的聚合数据类型.每个变量都叫做结构体的成员. type Employee struct { ID int Name string age int ...
- 项目版本管理Git使用详细教程
前言 记得刚开始做项目开发的时候都是一个人完成一个项目,单打独斗的开发,也不知道什么是团队开发,没有这个概念,随着工作后来知道公司里项目都是团队开发,这个时候这么多人怎么开发一个项目呢,难道用u盘拷贝 ...
- 备忘录——C#获取微信小程序的云数据库中数据
目录 0. 背景说明 0.2 获取AccessToken 0.3 数据库查询 0.4 文件下载 2. 简单的封装 3. 简单测试 4. 参考文档 shanzm-2021年8月17日 17:14:24 ...
- 云原生学习筑基 ~ 组网必备知识点 ~ DNS服务
@ 目录 一.为啥写这篇文章? 二.DNS的作用 三.域 四.DNS工作原理 五.搭建DNS服务器 5.1.Bind 5.2.系统环境准备 5.3.安装 5.4.查看bind的相关文件 5.5.查看b ...
- noip模拟45
A. 打表 首先注意这道题数组下标从 \(0\) 开始 可以找规律发现是 \(\displaystyle\frac{\sum |a_i-a _ {ans}|}{2^k}\) 那么严谨证明一下: 由于两 ...