Description

A square township has been divided up into n*m(n rows and m columns) square plots (1<=N,M<=8),some of them are blocked, others are unblocked. The Farm is located in the lower left plot and the Market is located in the lower right plot. Tony takes her tour of the township going from Farm to Market by walking through every unblocked plot exactly once. 
Write a program that will count how many unique tours Betsy can take in going from Farm to Market. 

Input

The input contains several test cases. The first line of each test case contain two integer numbers n,m, denoting the number of rows and columns of the farm. The following n lines each contains m characters, describe the farm. A '#' means a blocked square, a '.' means a unblocked square. 
The last test case is followed by two zeros. 

Output

For each test case output the answer on a single line.
 
题目大意:找到一条路径,经过所有非阻塞点,从右下到达左下。
思路:在最后加两排
.#######.
.......
 
代码(16MS):
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL; const int MAXN = ;
const int SIZEH = ;
const int MAXH = ; struct hash_map {
int head[SIZEH], size;
int state[MAXH], next[MAXH];
LL val[MAXH]; void init() {
memset(head, -, sizeof(head));
size = ;
} void insert(int st, LL sv) {
int h = st % SIZEH;
for(int p = head[h]; ~p; p = next[p]) {
if(state[p] == st) {
val[p] += sv;
return ;
}
}
state[size] = st; val[size] = sv; next[size] = head[h]; head[h] = size++;
}
} hashmap[]; hash_map *cur, *last;
int acc[] = {, -, , };
char mat[MAXN][MAXN];
int n, m, en, em; int getB(int state, int i) {
return (state >> (i << )) & ;
} void setB(int &state, int i, int val) {
state = (state & ~( << (i << ))) | (val << (i << ));
} int getLB(int state, int i) {
int ret = i, cnt = ;
while(cnt) {
--ret;
cnt += acc[getB(state, ret)];
}
return ret;
} int getRB(int state, int i) {
int ret = i, cnt = -;
while(cnt) {
++ret;
cnt += acc[getB(state, ret)];
}
return ret;
} 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->val[k]);
swap(cur, last);
}
}
for(int k = ; k < last->size; ++k)
if(last->state[k] == ) return last->val[k];
return ;
} int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n == && m == ) break;
memset(mat, , sizeof(mat));
for(int i = ; i < n; ++i) scanf("%s", mat[i]);
for(int i = ; i < m - ; ++i) mat[n][i] = '#';
n += ;
cout<<solve()<<endl;
}
}

POJ 1739 Tony's Tour(插头DP)的更多相关文章

  1. POJ 1739 Tony's Tour (插头DP,轮廓线DP)

    题意:给一个n*m的矩阵,其中#是障碍格子,其他则是必走的格子,问从左下角的格子走到右下角的格子有多少种方式. 思路: 注意有可能答案是0,就是障碍格子阻挡住了去路. 插头DP有两种比较常见的表示连通 ...

  2. [POJ 1739] Tony's Tour

    Link: POJ 1739 传送门 Solution: 这题除了一开始的预处理,基本上就是插头$dp$的模板题了 由于插头$dp$求的是$Hamilton$回路,而此题有起点和终点的限制 于是可以构 ...

  3. POJ 1739 Tony's Tour (DP)

    题意:从左下角到右下角有多少种走法. 析:特殊处理左下角和右下角即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000 ...

  4. POJ 2411 Mondriaan's Dream 插头dp

    题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...

  5. POJ 3133 Manhattan Wiring (插头DP,轮廓线,经典)

    题意:给一个n*m的矩阵,每个格子中有1个数,可能是0或2或3,出现2的格子数为2个,出现3的格子数为2个,要求将两个2相连,两个3相连,求不交叉的最短路(起终点只算0.5长,其他算1). 思路: 这 ...

  6. 【POJ】1739 Tony's Tour

    http://poj.org/problem?id=1739 题意:n×m的棋盘,'#'是障碍,'.'是空白,求左下角走到右下角且走过所有空白格子的方案数.(n,m<=8) #include & ...

  7. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  8. 插头DP题目泛做(为了对应WYD的课件)

    题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. #inc ...

  9. 【POJ】【1739】Tony's Tour

    插头DP 楼教主男人八题之一! 要求从左下角走到右下角的哈密顿路径数量. 啊嘞,我只会求哈密顿回路啊……这可怎么搞…… 容易想到:要是把起点和重点直接连上就变成一条回路了……那么我们就连一下~ 我们可 ...

随机推荐

  1. MYSQL命令简要笔记

    mysqldump "C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqldump.exe"    --host=localhost ...

  2. SQL语句中生成UUID方法

    SQL语句中生成UUID方法为UUID() 生成带横线UUID: select UUID()                         形如:abaffaca-fd55-11e5-b3d0-d2 ...

  3. 阿里云centOS7.4上MySql5.6安装

    最近一个项目要部署在阿里云上,为了开发团队方便,我自费买了个ECS,先装个数据库给开发用. 因为之前都是在真机安装,与这次阿里云上的部署比起来,还是有点区别的. Mysql 1 安装mysql版本包 ...

  4. shell入门基础&常见命令及用法

    shell shell是一个命令解释器,实际是一个程序,/bin/bash,linux中所有的命令都由它来解释,有自己的语法 shell脚本 以.sh结尾 shell语法+linux命令 注释: 单行 ...

  5. mysql的length与char_length的区别

    length:   是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符 char_length:不管汉字还是数字或者是字母都算是一个字符 同时这两个函数,可用于判断数据中是否有中文文字 例 ...

  6. 【一】调通单机版的thrift-python版本

    开发步骤说明 [任务1]调通单机版的thrift-python版本 [任务1]调通单机版的thrift-python版本 安装thrift 创建thrift模块文件并编译 开发python版的clie ...

  7. C++函数调用之——值传递、指针传递、引用传递

    1.简介 1.值传递:形参时实参的拷贝,改变函数形参并不影响函数外部的实参,这是最常用的一种传递方式,也是最简单的一种传递方式.只需要传递参数,返回值是return考虑的:使用值传递这种方式,调用函数 ...

  8. python 两个面试题

    1.下面程序的运算结果是什么?? class Parent: def func(self): print("In Parent func") def __init__(self): ...

  9. sas简单使用

    1 数据存取: 逻辑库: libname  自己起的名字 ‘文件所在的路径’,若无这步数据则存在默认的work中. 另一个方法在sas里自己建立一个逻辑库,但是关闭后就消失了. 新建数据:data  ...

  10. python中利用少量代码快速实现从类对象中抽取所需属性的一种实践

    项目中有可能会碰到这样一种场景: 根据一个id,查询得到和id对应的完整数据信息存储对象,比如书籍id到书籍详细信息,用户id到用户详细信息等,详细信息字段可能包括几十甚至上百个数据字段,真正需要返回 ...