这是一道经典的插头DP单回路模板题。

  用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制。

  1、当同时存在左、上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连;若不相同,则把这两个连通块连起来。

  2、如果只存在左或上插头的时候,则要延续连通块。

  3、若都不存在左和上插头的时候,就要新建一个连通块。

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm> using namespace std; #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define DWN(i, a, b) for (int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define mset(a, b) memset(a, b, sizeof(a))
typedef long long LL;
const int MAXD = , HASH = , STATE = ;
int n, m, maze[MAXD][MAXD], code[MAXD], ch[MAXD], end_x, end_y;
char str[MAXD];
struct HASHMAP
{
int head[HASH], nxt[STATE], siz; LL f[STATE], state[STATE];
void clear() { siz = , mset(head, -); }
void push(LL x, LL add)
{
int pos = x%HASH, i = head[pos];
for (; i != -; i = nxt[i])
if (state[i] == x) { f[i] += add; return ; }
state[siz] = x, f[siz] = add;
nxt[siz] = head[pos], head[pos] = siz++;
}
}hm[]; void in()
{
scanf("%d %d", &n, &m), mset(maze, ), end_x = end_y = -;
REP(i, , n)
{
scanf("%s", str+);
REP(j, , m)
if (str[j] == '.')
maze[i][j] = , end_x = i, end_y = j;
}
} void decode(LL x)
{
REP(i, , m) code[i] = x&, x >>= ;
} LL encode()
{
LL ret = ; int cnt = ;
mset(ch, -), ch[] = ;
DWN(i, m, )
{
if (ch[code[i]] == -) ch[code[i]] = ++cnt;
ret <<= , ret |= ch[code[i]];
}
return ret;
} void shift(int j)
{
if (j != m) return ;
DWN(i, m, ) code[i] = code[i-];
code[] = ;
} void dp_blank(int i, int j, int cur)
{
REP(k, , hm[cur].siz-)
{
decode(hm[cur].state[k]);
int lef = code[j-], up = code[j];
if (lef && up)
{
if (lef == up && !(i == end_x && j == end_y)) continue ;
REP(t, , m)
if (code[t] == up) code[t] = lef;
code[j-] = code[j] = , shift(j);
hm[cur^].push(encode(), hm[cur].f[k]);
}
else
if (lef || up)
{
int t = lef ? lef : up;
if (maze[i][j+])
{
code[j-] = , code[j] = t;
hm[cur^].push(encode(), hm[cur].f[k]);
}
if (maze[i+][j])
{
code[j-] = t, code[j] = , shift(j);
hm[cur^].push(encode(), hm[cur].f[k]);
}
}
else
if (maze[i][j+] && maze[i+][j])
{
code[j-] = code[j] = , shift(j);
hm[cur^].push(encode(), hm[cur].f[k]);
}
}
} void dp_block(int i, int j, int cur)
{
REP(k, , hm[cur].siz-)
{
decode(hm[cur].state[k]), shift(j);
hm[cur^].push(encode(), hm[cur].f[k]);
}
} void work()
{
int cur = ; LL ans = ;
hm[].clear(), hm[].clear(), hm[cur].push(, );
REP(i, , n)
REP(j, , m)
{
if (maze[i][j]) dp_blank(i, j, cur);
else dp_block(i, j, cur);
hm[cur].clear(), cur ^= ;
}
REP(i, , hm[cur].siz-) ans += hm[cur].f[i];
printf("%I64d\n", ans);
} int main()
{
in();
work();
return ;
}

Ural 1519 Formula 1 插头DP的更多相关文章

  1. 【BZOJ1814】Ural 1519 Formula 1 插头DP

    [BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...

  2. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 924  Solved: 351[Submit][Sta ...

  3. bzoj 1814 Ural 1519 Formula 1 插头DP

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 942  Solved: 356[Submit][Sta ...

  4. bzoj 1814 Ural 1519 Formula 1 ——插头DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...

  5. BZOJ1814: Ural 1519 Formula 1(插头Dp)

    Description Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic gam ...

  6. bzoj 1814: Ural 1519 Formula 1 插头dp经典题

    用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...

  7. 【Ural】1519. Formula 1 插头DP

    [题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...

  8. 【BZOJ1814】Ural 1519 Formula 1 (插头dp)

    [BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...

  9. ural 1519 Formula 1(插头dp)

    1519. Formula 1 @ Timus Online Judge 干了一天啊!!!插头DP入门. 代码如下: #include <cstdio> #include <cstr ...

随机推荐

  1. 解决Chrome下表单自动填充后背景色为黄色

    Chrome浏览器在表单自动填充后会显示黄色背景,这是Chrome的私有属性导致,对于有洁癖的人来讲,是不喜欢的,我们可以手动去掉. 代码如下: input:-webkit-autofill { -w ...

  2. frameset测试

    frame不能放在body标签内.指定name属性,为这一个框架指定名字,在html的a的target属性可以设为target="right"在该框架显示跳转的页面.(常用于后台管 ...

  3. arch点击硬盘无法挂载

    出现问题如下 在使用xfce4桌面的时候在点击硬盘图标时可以挂载虽然要求你输入root密码 但是在使用openbox的时候点击硬盘图标却出现如下提示,权限的问题 Not authorized to p ...

  4. python 并发爬虫的快感

    import time from tomorrow import threads from requests_html import HTMLSession session=HTMLSession() ...

  5. python3.6升级及setuptools、pip安装

    升级python3.6 1.打开官网www.python.org,找到最新3.6.3版本,复制下载链接 2.创建/app目录,wget下载到该目录下,编译安装 mkdir /app cd /app w ...

  6. JavaSE项目之员工收录系统

    在Java SE中,对IO流与集合的操作在应用中比较重要.接下来,我以一个小型项目的形式,演示IO流.集合等知识点在实践中的运用. 该项目名称为“员工收录系统”,主要是通过输入员工的id.姓名信息,实 ...

  7. xshell 映射带跳板机服务器的端口到本地

    1.配置xshell连接跳板机服务器: 2. 3.可用navicate等同过端口连接远程数据库.

  8. SP 页面缓存以及清除缓存

    JSP 页面缓存以及清除缓存 一.概述 缓存的思想可以应用在软件分层的各个层面.它是一种内部机制,对外界而言,是不可感知的. 数据库本身有缓存,持久层也可以缓存.(比如:hibernate,还分1级和 ...

  9. 查看压缩包内容tar -tf

    linux 压缩文件内容查看 分类:Linux | 标签: linux  压缩文件内容查看  2012-03-14 22:01阅读(1243)评论(0) 1. zipinfo    执行zipinfo ...

  10. css绘制图标

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...