好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错。

昨天看到的这题。

百度之后发现没有人发题解,hust也没,hdu也没discuss。。。在acm-icpc信息站发现难得的一篇题解。不过看到是插头二字之后,代码由于风格太不一样就没看了,自己想了好久,想通了。然后就等到今天才码。。。。

如果把点看成网格,那就可以实现,没有公共点公共边等限定条件,也显然是插头dp的最短单回路的模型。这是本题的一个难点(当时想到这样是因为,题目要求计算最短周长,显然这样建模便于求解)

另一个难点是如何保证那些OOXX在该在的位置,即题目所要求,O在单回路内部,X在单回路外部。我的做法是标记,加多一维01表示当前交点的左上角格子是否在内部。转移过程注意判断后续状态可否行即可。

这题要括号匹配,显然要用哈希表而不用数组。。。

虽然折腾时间挺久,但是1A的感觉还是不错的。

建议画图(其实所有插头dp都建议画图,便于分析,也不会占着电脑坑队友)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std; #define inf 0x3f3f3f3f
#define eps 1e-8
#define ll long long
#define maxm 51000 #define STATE 510000
#define HASH 10007
#define maxd 15 int n,m;
char maze[maxd][maxd];
int code[maxd];
struct HASHMAP{
int head[HASH],nxt[STATE],sz;
int state[STATE],f[STATE];
void clear(){sz=0;memset(head,-1,sizeof(head));}
void push(int st,int ans){
int h = st%HASH;
for(int i=head[h];i!=-1;i=nxt[i]){
if(st==state[i]){
f[i] = min(f[i], ans);
return ;
}
}
state[sz]=st, f[sz]=ans, nxt[sz]=head[h];
head[h]=sz++;
}
}hm[2][2];
void decode(int st){
for(int i=0;i<=m;++i) code[i] = st&3, st>>=2;
}
int encode(){
int ret=0;
for(int i=m;i>=0;--i) ret = ret<<2|code[i];
return ret;
}
bool jud(int i,int j,int in){
if(maze[i][j]=='o') return in;
if(maze[i][j]=='x') return !in;
return true;
}
int edx,edy;
int ans;
void dp(int i,int j,int cur,int in){
int xo = (1<<(j*2));
int ox = (2<<(j*2));
int oo = xo|ox;
int mv = (j==m?2:0);
for(int k=0;k<hm[cur][in].sz;++k){
decode(hm[cur][in].state[k]);
int left = code[j-1];
int up = code[j];
if(left && up){
if(left==2 && up==1){
if(i>=edx+1 && j>=edy+1){
int to = hm[cur][in].state[k] ^ (ox>>2) ^ (xo);
if(to==0) ans = min(ans, hm[cur][in].f[k]+1);
}
continue;
}
if(left==1 && up==1){
for(int jj=j-1,c=0;jj>=0;--jj){
if(code[jj]==1)++c;
if(code[jj]==2)--c;
if(c==0){code[jj]^=3;break;}
}
code[j-1]=code[j]=0;
}
if(left==2 && up==2){
for(int jj=j,c=0;jj<=m;++jj){
if(code[jj]==2)++c;
if(code[jj]==1)--c;
if(c==0){code[jj]^=3;break;}
}
code[j-1]=code[j]=0;
}
if(left==1 && up==2){
code[j-1]=code[j]=0;
}
if(jud(i-1,j,in^1))
hm[cur^1][in^1].push(encode()<<mv, hm[cur][in].f[k]+1);
}else if(left || up){
int in2 = in;
if(up) in2^=1;
int tmp = left | up;
code[j-1]=tmp, code[j]=0;
if(i+1<=n)
if(jud(i-1,j,in2) && jud(i,j-1,!in2) && jud(i,j,in2))
hm[cur^1][in2].push(encode()<<mv, hm[cur][in].f[k]+1);
code[j-1]=0, code[j]=tmp;
if(j+1<=m)
if(jud(i-1,j,in2) && jud(i,j-1,!in2) && jud(i,j,!in2))
hm[cur^1][in2].push(encode()<<mv, hm[cur][in].f[k]+1);
}else {
if(jud(i-1,j,in) && jud(i,j-1,in) && jud(i,j,in))
hm[cur^1][in].push(hm[cur][in].state[k]<<mv, hm[cur][in].f[k]);
code[j-1]=2, code[j]=1;
if(i+1<=n && j+1<=m)
if(jud(i-1,j,in) && jud(i,j-1,in) && jud(i,j,!in))
hm[cur^1][in].push(encode()<<mv, hm[cur][in].f[k]+1);
}
}
}
int solve(){
int cur=0;
hm[0][0].clear();
hm[0][1].clear();
hm[0][0].push(0,0);
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(maze[i][j]=='o') edx=i,edy=j;
ans=inf;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
hm[cur^1][0].clear();
hm[cur^1][1].clear();
dp(i,j,cur,0);
dp(i,j,cur,1);
cur^=1;
}
}
if(ans==inf) return -1;
return ans;
}
int main(){
int t,ca=0;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(maze,0,sizeof(maze));
for(int i=1;i<=n;++i) scanf("%s",maze[i]+1);
++n,++m;
for(int i=0;i<=n;++i) maze[i][0]=maze[i][m]='.';
for(int j=0;j<=m;++j) maze[0][j]=maze[n][j]='.';
printf("Case #%d: %d\n",++ca, solve());
}
return 0;
}

HDU 4113 Construct the Great Wall(插头dp)的更多相关文章

  1. HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)

    插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...

  2. HDU 1693 Eat the Trees(插头DP,入门题)

    Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudge is a ...

  3. HDU 1693 Eat the Trees (插头DP)

    题意:给一个n*m的矩阵,为1时代表空格子,为0时代表障碍格子,问如果不经过障碍格子,可以画一至多个圆的话,有多少种方案?(n<12,m<12) 思路: 这题不需要用到最小表示法以及括号表 ...

  4. HDU 1693 二进制表示的简单插头dp

    题目大意: 找到多条回路覆盖所有非障碍格子,问这样回路的种数 这里的插头与URAL1519 不一样的是 只要管它是否存在即可,只需要1个二进制位表示状态 #include <cstdio> ...

  5. HDU 1565 方格取数(1) ——插头DP

    [题目分析] 其实直接状压就可以了. 但是有点闲,又写了一个可读性极差,智商低下,很(gou)好(pi)的代码 [代码] #include <cstdio> #include <cs ...

  6. hdu 1693 : Eat the Trees 【插头dp 入门】

    题目链接 题意: 给出一个n*m大小的01矩阵,在其中画线连成封闭图形,其中对每一个值为1的方格,线要恰好穿入穿出共两次,对每一个值为0的方格,所画线不能经过. 参考资料: <基于连通性状态压缩 ...

  7. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

  8. hdu 1693 Eat the Trees——插头DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...

  9. HDU 4949 Light(插头dp、位运算)

    比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...

随机推荐

  1. 微信小程序之页面路由(九)

    [未经允许,请勿以任何形式转载] 什么是路由? 我们通常理解的路由指分组数据包从源到目的地时,决定端到端路径的网络范围的进程: 借用上面的定义,我们可以理解小程序页面路由,根据路由规则(路径)从一个页 ...

  2. AutoHotKey实现将站点添加到IE的Intranet本地站点

    最近在内部推行CRM系统,其中的CPQ组件要求必须将站点加入到"本地Intranet”才可以正常使用,但是由于使用用户比较多(超过几千人),并且每个用户的计算机水平都不一样,所以让用户手工去 ...

  3. 二维RMQ

    求二维ST表 ;k<=;k++) ;l<=;l++) ;i<=n;i++) ;j<=m;j++){ <<(l-)),m+),tx=min(n+,i+(<< ...

  4. 2016 Web开发资源工具大搜罗

    来源于:https://zhuanlan.zhihu.com/p/22730771 作者:余博伦链接:https://zhuanlan.zhihu.com/p/22730771来源:知乎著作权归作者所 ...

  5. ScrollView中嵌套recycleView 出现的不显示,显示不全,终极解决方案

    最近公司项目中用到了ScrollView去嵌套recycleView, 最开始我天真的把recycleView直接放入scrollView中,结果可想而知,什么都不显示,瞬间懵逼,我心想应该是和嵌套L ...

  6. Spring+EhCache缓存实例

    一.ehcahe的介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider.Ehcache是一种广泛使用的开源Java分布式 ...

  7. Mysql 视图 游标 触发器 存储过程 事务

    Mysql 视图 触发器 存储过程 游标 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中 ...

  8. POJ 2942 Knights of the Round Table

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 10911   Acce ...

  9. 【Beta】Scrum5.5

    Info 时间:2016.12.13 21:45 时长:15min 地点:大运村1号公寓5楼楼道 类型:日常Scrum会议 NXT:2016.12.15 21:30 Task Report Name ...

  10. 【Beta】第四次任务发布

    PM 日常管理&dev版宣传(周日开始). 后端 #99 服务发布 验收条件:使dev版能在www.buaaphylab.com下运行. 前端 #87 登录后能够查看与下载用户收藏的报告.生成 ...