【插头DP】BZOJ1814-Formula
【题目大意】
给出一个m*n的矩阵里面有一些格子为障碍物,求经过所有非障碍格子的哈密顿回路个数。
【思路】
最典型的插头DP。分为三种情况:
(1)当前格子既没有上插头也没有左插头。
如果下边和右边都没有障碍,新建连同分量。
(2)如果只有左插头或者右插头。
延伸或者拐弯,当然也要判断有没有障碍。
(3)上插头和左插头都没有。
1. 如果两个插头不连通(编号不一样),那么将两个插头所处的连通分量合并,标记相同的连通块标号,O(n)扫描保证最小表示;
2. 如果已经连通,相当于出现了一个回路,这种情况只能出现在最后一个非障碍格子。
由于状态非常多,用hash表存储状态。
decode和encode注意一下,这里不赘述了。
【错误点】
注意一下ch要开得够大,具体见代码。
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<vector>
- using namespace std;
- typedef long long ll;
- const int MAXN=;
- const int HASH=;
- int ex,ey;
- int m,n;
- int maze[MAXN][MAXN];
- int code[MAXN],ch[MAXN];
- struct HashMap
- {
- vector<int> hash[HASH];//存储f和state的下标
- vector<ll> f,state;//存储对应的方案数和状态
- void init()
- {
- for (int i=;i<HASH;i++) vector<int>().swap(hash[i]);
- vector<ll>().swap(f);
- vector<ll>().swap(state);
- }
- void push(ll st,ll ans)
- {
- int h=st%HASH;
- for (int i=;i<hash[h].size();i++)
- {
- int now=hash[h][i];
- if (state[now]==st)//如果已经存储了当前状态,直接累加
- {
- f[now]+=ans;
- return;
- }
- }
- //如果没有存储过当前状态,累加
- state.push_back(st);
- f.push_back(ans);
- hash[h].push_back(state.size()-);
- }
- }dp[];
- void decode(ll st)
- {
- memset(code,,sizeof(code));
- for (int i=n;i>=;i--)
- {
- code[i]=st&;//每三位代表一个信息
- st>>=;
- }
- }
- ll encode()
- //用最小表示法重新编码
- {
- int cnt=;
- memset(ch,-,sizeof(ch));
- ch[]=;
- long long st=;
- for (int i=;i<=n;i++)
- {
- if (ch[code[i]]==-) ch[code[i]]=cnt++;
- code[i]=ch[code[i]];
- st<<=;
- st|=code[i];
- }
- return st;
- }
- void shift()
- {
- for (int i=n;i>;i--) code[i]=code[i-];
- code[]=;
- }
- void dpblank(int i,int j,int cur)
- {
- for (int k=;k<dp[-cur].state.size();k++)
- {
- decode(dp[-cur].state[k]);
- int left=code[j-];//左插头
- int up=code[j];//上插头
- /*如果上下插头都没有*/
- if (!left && !up)
- {
- if (maze[i][j+] && maze[i+][j])
- {
- code[j-]=code[j]=MAXN-;
- //这里只要随便设置一个大数即可
- //【attention】这里千万不可以设置成MAXN,否则ch数组会抱★★★★★★★★
- //因为encode会重新用最小表示法编码
- dp[cur].push(encode(),dp[-cur].f[k]);
- }
- }
- /*只有上插头或者只有左插头*/
- if ((left&&(!up))||((!left)&&up))
- {
- int t=left|up;
- if (maze[i][j+])//右边没有障碍
- {
- code[j-]=;
- code[j]=t;
- dp[cur].push(encode(),dp[-cur].f[k]);
- }
- if (maze[i+][j])//下面没有障碍
- {
- code[j-]=t;
- code[j]=;
- if (j==n) shift();
- dp[cur].push(encode(),dp[-cur].f[k]);
- }
- }
- /*上插头和右插头都有*/
- if (left && up)
- {
- if (left==up)
- {
- if (i==ex && j==ey)
- {
- code[j-]=code[j]=;
- if (j==n) shift();
- dp[cur].push(encode(),dp[-cur].f[k]);
- }
- }
- else
- {
- code[j-]=code[j]=;
- for (int t=;t<=n;t++)
- if (code[t]==up) code[t]=left;
- if (j==n) shift();
- dp[cur].push(encode(),dp[-cur].f[k]);
- }
- }
- }
- }
- void dpblock(int i,int j,int cur)
- {
- int k=;
- for (int k=;k<dp[-cur].state.size();k++)
- {
- decode(dp[-cur].state[k]);
- code[j-]=code[j]=;
- if (j==n) shift();
- dp[cur].push(encode(),dp[-cur].f[k]);
- }
- }
- void solve()
- {
- int cur=;
- ll ans=;
- dp[cur].init();
- dp[cur].push(,);//DP数组初始化
- for (int i=;i<=m;i++)
- for (int j=;j<=n;j++)
- {
- cur^=;
- dp[cur].init();
- if (maze[i][j]) dpblank(i,j,cur);
- else dpblock(i,j,cur); }
- for (int i=;i<dp[cur].state.size();i++)
- ans+=dp[cur].f[i];
- printf("%lld",ans);
- }
- void init()
- {
- memset(maze,,sizeof(maze));
- ex=ey=;
- for (int i=;i<=m;i++)
- {
- char str[MAXN];
- scanf("%s",str);
- for (int j=;j<n;j++)
- {
- if (str[j]=='.')
- {
- ex=i;
- ey=j+;
- maze[i][j+]=;
- }
- }
- }
- }
- int main()
- {
- while (scanf("%d%d",&m,&n)!=EOF)
- {
- init();
- if (ex==) puts("");//如果没有一个是空格的话直接输出0
- else solve();
- }
- return ;
- }
【插头DP】BZOJ1814-Formula的更多相关文章
- 【BZOJ1814】Ural 1519 Formula 1 (插头dp)
[BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...
- 【BZOJ1814】Ural 1519 Formula 1 插头DP
[BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...
- bzoj1814 Ural 1519 Formula 1(插头dp模板题)
1814: Ural 1519 Formula 1 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 924 Solved: 351[Submit][Sta ...
- bzoj1814 Ural 1519 Formula 1(插头DP)
对插头DP的理解还不是很透彻. 先说一下肤浅的理解吧. 插头DP使用范围:指数级复杂度,且适用于解决网格图连通性问题,如哈密顿回路等问题.插头一般指每相邻2个网格的接口. 题目难度:一般不可做. 使用 ...
- 插头DP讲解+[BZOJ1814]:Ural 1519 Formula 1(插头DP)
1.什么是插头$DP$? 插头$DP$是$CDQ$大佬在$2008$年的论文中提出的,是基于状压$D$P的一种更高级的$DP$多用于处理联通问题(路径问题,简单回路问题,多回路问题,广义回路问题,生成 ...
- 【Ural】1519. Formula 1 插头DP
[题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...
- RUAL1519 Formula 1 【插头DP】
RUAL1519 Formula 1 Background Regardless of the fact, that Vologda could not get rights to hold the ...
- URAL 1519 Formula 1(插头DP,入门题)
Description Background Regardless of the fact, that Vologda could not get rights to hold the Winter ...
- URAL1519 Formula 1 —— 插头DP
题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 secondMemory limit: 64 MB ...
- ural 1519 Formula 1(插头dp)
1519. Formula 1 @ Timus Online Judge 干了一天啊!!!插头DP入门. 代码如下: #include <cstdio> #include <cstr ...
随机推荐
- 面向对象 ( OO ) 的程序设计——继承
本文地址:http://www.cnblogs.com/veinyin/p/7608282.html 仅支持实现继承,且主要依靠原型链来实现,不过一般会混合构造函数一起实现继承 1 原型链 继承使用 ...
- Yii2 的 redis 应用
在应用的时候需要先对yii2进行扩展安装 如果装有composer直接运行 php composer.phar require --prefer-dist yiisoft/yii2-redis 当然也 ...
- [AHOI2012]树屋阶梯 题解(卡特兰数)
[AHOI2012]树屋阶梯 Description 暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题.由于地上露营湿气重,必须选择在高处的树屋露营. ...
- 【leetcode 简单】第二十七题 二叉树的最小深度
给定一个二叉树,找出其最小深度. 最小深度是从根节点到最近叶子节点的最短路径上的节点数量. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], ...
- redis中插入用户集合的语句,有四个属性
一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...
- CentOS7.4 安装 oracle12c
安装依赖 yum install -y binutils.x86_64 compat-libcap1.x86_64 gcc.x86_64 gcc-c++.x86_64 glibc.i686 glibc ...
- LFM隐语义模型Latent Factor Model
实际应用 LFM 模型在实际使用中有一个困难,就是很难实现实时推荐.经典的 LFM 模型每次训练都需要扫描所有的用户行为记录,并且需要在用户行为记录上反复迭代来优化参数,所以每次训练都很耗时,实际应用 ...
- linux下rz,sz安装
1.sz rz yum安装 yum install lrzsz
- 关于VS2010的一些操作
自动插入接口实现 1: class MyClass : IMyInterface 2: { 3: 4: } .csharpcode, .csharpcode pre { font-size: sm ...
- spring mvc整合mybaitis和log4j
在上一篇博客中,我介绍了在mac os上用idea搭建spring mvc的maven工程,但是一个完整的项目肯定需要数据库和日志管理,下面我就介绍下spring mvc整合mybatis和log4j ...