Description

Background

Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic games of 20**, it is well-known, that the city will conduct one of the Formula 1 events. Surely, for such an important thing a new race circuit should be built as well as hotels, restaurants, international airport - everything for Formula 1 fans, who will flood the city soon. But when all the hotels and a half of the restaurants were built, it appeared, that at the site for the future circuit a lot of gophers lived in their holes. Since we like animals very much, ecologists will never allow to build the race circuit over the holes. So now the mayor is sitting sadly in his office and looking at the map of the circuit with all the holes plotted on it.

Problem

Who will be smart enough to draw a plan of the circuit and keep the city from inevitable disgrace? Of course, only true professionals - battle-hardened programmers from the first team of local technical university!.. But our heroes were not looking for easy life and set much more difficult problem: "Certainly, our mayor will be glad, if we find how many ways of building the circuit are there!" - they said.
It should be said, that the circuit in Vologda is going to be rather simple. It will be a rectangle N* M cells in size with a single circuit segment built through each cell. Each segment should be parallel to one of rectangle's sides, so only right-angled bends may be on the circuit. At the picture below two samples are given for N = M = 4 (gray squares mean gopher holes, and the bold black line means the race circuit). There are no other ways to build the circuit here.

Input

The first line contains the integer numbers N and M (2 ≤ N, M ≤ 12). Each of the next N lines contains M characters, which are the corresponding cells of the rectangle. Character "." (full stop) means a cell, where a segment of the race circuit should be built, and character "*" (asterisk) - a cell, where a gopher hole is located.

Output

You should output the desired number of ways. It is guaranteed, that it does not exceed 2 63-1.
 
题目大意:找一个环,经过所有是'.'的点一次,问有多少个这样的哈密尔顿环。
思路:插头DP,参考IOI国家集训队论文,陈丹琦的《基于连通性状态压缩的动态规划问题》
PS:本来想不用hash的,但是写完发现状态根本存不下啊魂淡
 
代码(78MS):(Update:2014年11月14日)
 #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,入门题)的更多相关文章

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

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

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

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

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

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

  4. 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 ...

  5. Ural 1519 Formula 1 插头DP

    这是一道经典的插头DP单回路模板题. 用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制. 1.当同时存在左.上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连 ...

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

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

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

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

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

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

  9. [URAL1519] Formula 1 [插头dp入门]

    题面: 传送门 思路: 插头dp基础教程 先理解一下题意:实际上就是要你求这个棋盘中的哈密顿回路个数,障碍不能走 看到这个数据范围,还有回路处理,就想到使用插头dp来做了 观察一下发现,这道题因为都是 ...

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

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

随机推荐

  1. Python的多进程

    这里不说其它,Python的多进程网上已经有很多了,可以尽情搜索.但是用多进程一般是采用对任务的方式,所以注意文件锁定.一般采用Pool是比较合适的.给个网友的小代码 from multiproces ...

  2. javascript中的栈堆内存

    <--------栈内存---------> 俗称叫做作用域(全局作用域/私有作用域) >为js代码提供的执行环境(执行js代码的地方) >基本数据内省是直接存放在栈内存中的 ...

  3. 第一个electron

    1 开发环境:node环境 2 下载electron:npm install electron --save-dev 3 package.json配置如下: { "name": & ...

  4. Mybatis根据数据库中的表自动生成Bean对象与Mapper文件 (小白式教程)

    示例IDE采用 IDEA //**********************华丽的分割线****************// 1.新建一个java项目-->在Src目录下创建3个包(Package ...

  5. 关于Quartz 2D绘图的简单使用

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ...

  6. 使用js实现单向绑定

    详细解释单向绑定 参考资料 MDN addEventListener()定义与用法 <!DOCTYPE html> <html lang="en"> < ...

  7. 「PHP」简单工厂模式

    引言   所属:创建型模式,常用设计模式之一 工厂模式分为:简单工厂模式.工厂方法模式.静态工厂模式.抽象工厂模式. 下面为简单工厂模式.   参考资料: <大话设计模式>程杰   模式概 ...

  8. 配置一个nginx+php-fpm的web服务器

    一.基本信息 系统(L):CentOS 6.9 #下载地址:http://mirrors.sohu.com 反代&负载均衡(N):NGINX 1.14.0 #下载地址:http://nginx ...

  9. ruby中url解码并替换非法字符

    url中中文字符解码 str = URI.decode(url_str) 替换非法字符 if ! str.valid_encoding? p str = str.encode("UTF-16 ...

  10. Stream的顺序流与并行流

    /** * @auther hhh * @date 2019/1/2 22:52 * @description */ public class StreamAPI2 { /** * 流的特性:支持并行 ...