URAL 1519 Formula 1(插头DP,入门题)
Description
Background
Problem
Input
Output
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL; const int MAXH = ;
const int SIZEH = ; struct hash_map {
int head[SIZEH];
int next[MAXH], state[MAXH];
LL value[MAXH];
int size; void init() {
memset(head, -, sizeof(head));
size = ;
} void insert(int st, LL tv) {
int h = st % SIZEH;
for(int i = head[h]; ~i; i = next[i]) {
if(state[i] == st) {
value[i] += tv;
return ;
}
}
value[size] = tv; state[size] = st;
next[size] = head[h]; head[h] = size++;
}
} hashmap[]; hash_map *cur, *last;
int acc[] = {, -, , }; int n, m, en, em;
char mat[][]; int getB(int state, int i) {
i <<= ;
return (state >> i) & ;
} int getLB(int state, int i) {
int ret = i, cnt = ;
while(cnt) cnt += acc[getB(state, --ret)];
return ret;
} int getRB(int state, int i) {
int ret = i, cnt = -;
while(cnt) cnt += acc[getB(state, ++ret)];
return ret;
} void setB(int &state, int i, int tv) {
i <<= ;
state = (state & ~( << i)) | (tv << i);
} void update(int x, int y, int state, LL tv) {
int left = getB(state, y);
int up = getB(state, y + );
if(mat[x][y] == '*') {
if(left == && up == ) cur->insert(state, tv);
return ;
}
if(left == && up == ) {
if(x == n - || y == m - ) return ;
int newState = state;
setB(newState, y, );
setB(newState, y + , );
cur->insert(newState, tv);
} else if(left == || up == ) {
if(x < n - ) {
int newState = state;
setB(newState, y, up + left);
setB(newState, y + , );
cur->insert(newState, tv);
}
if(y < m - ) {
int newState = state;
setB(newState, y, );
setB(newState, y + , up + left);
cur->insert(newState, tv);
}
} else {
int newState = state;
setB(newState, y, );
setB(newState, y + , );
if(left == && up == ) setB(newState, getRB(state, y + ), );
if(left == && up == && !(x == en && y == em)) return ;
if(left == && up == ) setB(newState, getLB(state, y), );
cur->insert(newState, tv);
}
} void findend() {
for(en = n - ; en >= ; --en)
for(em = m - ; em >= ; --em) if(mat[en][em] == '.') return ;
} LL solve() {
findend();
cur = hashmap, last = hashmap + ;
last->init();
last->insert(, );
for(int i = ; i < n; ++i) {
int sz = last->size;
for(int k = ; k < sz; ++k) last->state[k] <<= ;
for(int j = ; j < m; ++j) {
cur->init();
sz = last->size;
for(int k = ; k < sz; ++k)
update(i, j, last->state[k], last->value[k]);
swap(cur, last);
}
}
return last->size ? last->value[] : ;
} int main() {
scanf("%d%d", &n, &m);
for(int i = ; i < n; ++i) scanf("%s", mat[i]);
cout<<solve()<<endl;
}
URAL 1519 Formula 1(插头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 ...
- bzoj 1814: Ural 1519 Formula 1 插头dp经典题
用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...
- 【BZOJ1814】Ural 1519 Formula 1 插头DP
[BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...
- 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 ...
- Ural 1519 Formula 1 插头DP
这是一道经典的插头DP单回路模板题. 用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制. 1.当同时存在左.上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连 ...
- bzoj 1814 Ural 1519 Formula 1 ——插头DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...
- BZOJ1814: Ural 1519 Formula 1(插头Dp)
Description Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic gam ...
- 【Ural】1519. Formula 1 插头DP
[题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...
- [URAL1519] Formula 1 [插头dp入门]
题面: 传送门 思路: 插头dp基础教程 先理解一下题意:实际上就是要你求这个棋盘中的哈密顿回路个数,障碍不能走 看到这个数据范围,还有回路处理,就想到使用插头dp来做了 观察一下发现,这道题因为都是 ...
- 【BZOJ1814】Ural 1519 Formula 1 (插头dp)
[BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...
随机推荐
- 在mac下运行 npm run eject 出现报错问题解决方法
当使用create-react-app创建项目后,接着运行npm run eject时,如果出现下面的错误 可能是脚手架添加了.gitignore这个文件,但是没有本地仓库,可以使用以下代码解决这个问 ...
- <CPP学习 第二天> 字符串的输入 及 String类
今天简单的学习了字符串的输入以及C++的String类. 1.面向行的输入: getline(); getline()函数读取整行,通过回车键输入的换行符来确定输入结尾.要调用这种方法,可以使用cin ...
- Elasticsearch 聚合操作
数据准备: PUT /shop { "settings": { "number_of_shards": 3, "number_of_replicas& ...
- Elasticsearch 数据操作
一.新增数据 1.1 随机生成id 语法: POST /索引库名/类型名 { "key1": "value1", "key2": " ...
- Centos7 Redis3.0 集群搭建备忘
(要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下) 127.0.0.1:7000 127.0.0. ...
- 基于Geomesa服务查询轨迹数据无法根据空间和时间范围进行结果查询
一.Geomesa - QuickStart(教程工程包) 百度网盘下载地址:geomesa-tutorials-master.7z 二.解压后,IDEA编译如下 百度网盘下载地址:IDEA201 ...
- socketpair通信
1.线程间通信(参考安卓源码InputTransport.cpp) #include <pthread.h> #include <sys/types.h> /* See NOT ...
- python学习第三天 -----2019年4月23日
第三周-第03章节-Python3.5-集合及其运算 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 ...
- ruby语言里的self理解
关键的一句话:关键看谁调用self,self就属于谁 有3种情况: 1.在class或module的定义中,self代表这个class或者这个module对象,代码如下: class S puts ' ...
- 关于verilog中的signed类型
在数字电路中,出于应用的需要,我们可以使用无符号数,即包括0及整数的集合:也可以使用有符号数,即包括0和正负数的集合.在更加复杂的系统中,也许这两种类型的数,我们都会用到. 有符号数通常以2的补码形式 ...