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 NM 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 ≤ NM ≤ 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. activemq整合springboot使用(个人微信小程序用)

    1.引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spri ...

  2. MySQL语句整理(二)

    数据库操作前的准备 -- 创建数据库 -- create database python_test_1 charset=utf8; -- 使用数据库 -- use python_test_1; -- ...

  3. CentOS6.5 虚拟机 磁盘扩容

    1. 关闭虚拟机 2. 编辑虚拟机设置:增加硬盘的置备大小,或者添加新的硬盘 3. 启动虚拟机,查看可用磁盘大小 : # df -Th Filesystem Type Size Used Avail ...

  4. Action与Func 用法

    //vs2017 + framework4.6.2 //zip    https://github.com/chxl800/ActionFuncDemo //源文件git   https://gith ...

  5. Jquery拼图

    Jquery代码 <script> $(function () { $("td").click(function () { var img = $(this).prop ...

  6. MySQL数据库 : 函数和存储过程

    CONCAT 可以把多个字符串连在一起,如把 doc_id 和 title这两个字段的查询结果组合成一个字符串:SELECT CONCAT(doc_id,title) FROM simhash; CO ...

  7. 【Storm一】Storm安装部署

    storm安装部署 解压storm安装包 $ tar -zxvf apache-storm-1.1.0.tar.gz -C /usr/local/src 修改解压后的apache-storm-1.1. ...

  8. 【NXP开发板应用—智能插排】4. PWM驱动

    [前言] 首先感谢深圳市米尔科技有限公司举办的这次活动并予以本人参加这次活动的机会,以往接触过嵌入式,但那都是皮毛,最多刷个系统之类的,可以说对于嵌入式系统开发这件事情是相当非常陌生的,这次活动为我提 ...

  9. Java Integer == 以及分析

    Java Integer == 先看一下这段代码 Integer integer1 = 100; Integer integer2 = 100; System.out.println("in ...

  10. HDU 5212 莫比乌斯反演

    Code Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...