这是一道经典的插头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. 商城项目(ssm+dubbo+nginx+mysql统合项目)总结(3)

    我不会在这里贴代码和详细步骤什么的,我觉得就算我把它贴出来,你们照着步骤做还是会出很多问题,我推荐你们去看一下黑马的这个视频,我个人感觉很不错,一步一步走下来可以学到很多东西.另外,视频和相关文档的话 ...

  2. 自定义ISO结构

    流程: 1.OS安装 1.1 网卡配置 1.2 密码 1.3 语言 1.4 时区 1.5 分区 1.6 rpms ... 2.软件安装 2.1 BIC Server 2.2 APP Server 2. ...

  3. python3.4.3安装allure2记录

    一.安装:cmd执行命令pip install allure-pytest 二.下载allure2:2.7.0版本 https://dl.bintray.com/qameta/generic/io/q ...

  4. Codeforces Round #434 (Div. 2)

    Codeforces Round #434 (Div. 2) 刚好时间对得上,就去打了一场cf,发现自己的代码正确度有待提高. A. k-rounding 题目描述:给定两个整数\(n, k\),求一 ...

  5. 002_让你的linux虚拟终端五彩缤纷(1)——LS颜色设置

  6. 20行js代码制作网页刮刮乐

    分享一段用canvas和JS制作刮刮乐的代码,JS部分去掉注释不到20行代码效果如下 盖伦.jpg 刮刮乐.gif HTML部分 <body> ![](img/gailun.jpg) &l ...

  7. appium---【Mac】appium-doctor提示WARN:“fbsimctl cannot be found”解决方案

    报错提示截图如下: 解决方案: brew tap facebook/fb brew install fbsimctl --HEAD 执行完命令重新运营appium-doctor即可看到成功已安装此包:

  8. Hadoop案例(八)辅助排序和二次排序案例(GroupingComparator)

    辅助排序和二次排序案例(GroupingComparator) 1.需求 有如下订单数据 订单id 商品id 成交金额 0000001 Pdt_01 222.8 0000001 Pdt_05 25.8 ...

  9. hadoop环境安装及错误总结

    历时N天的hadoop环境,终于配好了 主要参考 Hadoop集群安装配置教程_Hadoop2.6.0_Ubuntu/CentOS 1.开机默认进入字符界面或者是图形界面:http://blog.cs ...

  10. C# 6.0 新特性 (三)

    主构造函数 自动属性初始化表达式尤其适合与主构造函数结合使用.主构造函数为降低常见对象模式的繁琐程度提供了一种方法.此功能自五月以来已显著改进.更新包括: 主构造函数的可选实现主体:这将支持此前不受支 ...