hdu 4856 Tunnels (记忆化搜索)
Tunnels
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 844 Accepted Submission(s): 249
Problem Description
Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In his eyes, the city is a grid. He can’t enter a grid with a barrier. In one minute, he can move into an adjacent grid with no barrier. Bob is full of curiosity and he wants to visit all of the secret tunnels beneath the city. To travel in a tunnel, he has to walk to the entrance of the tunnel and go out from the exit after a fabulous visit. He can choose where he starts and he will travel each of the tunnels once and only once. Now he wants to know, how long it will take him to visit all the tunnels (excluding the time when he is in the tunnels).
Input
The input contains mutiple testcases. Please process till EOF.
For each testcase, the first line contains two integers N (1 ≤ N ≤ 15), the side length of the square map and M (1 ≤ M ≤ 15), the number of tunnels.
The map of the city is given in the next N lines. Each line contains exactly N characters. Barrier is represented by “#” and empty grid is represented by “.”.
Then M lines follow. Each line consists of four integers x1, y1, x2, y2, indicating there is a tunnel with entrence in (x1, y1) and exit in (x2, y2). It’s guaranteed that (x1, y1) and (x2, y2) in the map are both empty grid.
Output
For each case, output a integer indicating the minimal time Bob will use in total to walk between tunnels.
If it is impossible for Bob to visit all the tunnels, output -1.
Sample Input
5 4
....#
...#.
.....
.....
.....
2 3 1 4
1 2 3 5
2 3 3 1
5 4 2 1
Sample Output
7
记忆化搜索

view code#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int dp[15][1<<15];
bool vis[15][1<<16];
int bit[25], n, m;
char str[20][20];
int dis[25][25], ans, tot;
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0}; struct node
{
int x, y, dis;
node() {}
node(int x, int y, int dis):x(x),y(y),dis(dis) {}
bool operator == (const node &o){
return x==o.x && y==o.y;
}
}; struct edge
{
node a, b;
}sto[20]; void init()
{
for(int i=0; i<20; i++) bit[i] = 1<<i;
} bool is_ok(int x, int y)
{
if(x<0 || x>=n || y<0 || y>=n || str[x][y]=='#') return 0;
return true;
} bool look[20][20];
int getdis(node a, node b)
{
queue<node >q;
q.push(node(a.x, a.y, 0));
memset(look, 0, sizeof(look));
look[a.x][a.y]=1;
while(!q.empty())
{
node o = q.front(); q.pop();
if(o==b) return o.dis;
for(int i=0; i<4; i++)
{
int x = o.x+dx[i], y = o.y+dy[i];
if(!is_ok(x, y) || look[x][y]) continue;
q.push(node(x, y, o.dis+1));
look[x][y] = 1;
}
}
return INF;
} int dfs(int u, int s)
{
if(vis[u][s]) return dp[u][s];
if(s==tot) return 0;
vis[u][s] = 1;
int &res = dp[u][s];
res = INF;
for(int i=0; i<n; i++)
{
if(bit[i]&s || u==i) continue;
res = min(dfs(i, s|bit[i])+dis[u][i], res);
}
return res;
} void solve()
{
for(int i=0; i<n; i++) scanf("%s", str[i]);
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d", &sto[i].a.x, &sto[i].a.y, &sto[i].b.x, &sto[i].b.y);
sto[i].a.x --; sto[i].a.y--; sto[i].b.x--; sto[i].b.y--;
for(int j=0; j<i; j++)
{
dis[i][j] = getdis(sto[i].b, sto[j].a);
dis[j][i] = getdis(sto[j].b, sto[i].a);
}
}
memset(vis, 0, sizeof(vis));
int ans = INF;
tot = bit[m]-1;
for(int i=0; i<m; i++){
int tmp = dfs(i, bit[i]);
ans = min(tmp, ans);
}
if(ans==INF) ans = -1;
printf("%d\n", ans);
} int main()
{
// freopen("in.txt", "r", stdin);
init();
while(scanf("%d%d", &n, &m)>0) solve();
return 0;
}
hdu 4856 Tunnels (记忆化搜索)的更多相关文章
- 不要62 hdu 2089 dfs记忆化搜索
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中 ...
- hdu 1078(dfs记忆化搜索)
题意:容易理解... 思路:我开始是用dfs剪枝做的,968ms险过的,后来在网上学习了记忆化搜索=深搜形式+dp思想,时间复杂度大大降低,我个人理解,就是从某一个点出发,前面的点是由后面的点求出的, ...
- hdu 4826(dp + 记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4826 思路:dp[x][y][d]表示从方向到达点(x,y)所能得到的最大值,然后就是记忆化了. #i ...
- POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)
题目大意:给你一个8*8的棋盘,上面有四个棋子,给你一个初始排布,一个目标排布,每次移动,可以把一个棋子移动到一个相邻的空位,或者跨过1个相邻的棋子,在保证棋子移动不超过8次的情况下,问能否把棋盘上的 ...
- hdu 4345 Permutation 记忆化搜索
思路:实际上求的是和小于等于n的质数的种类数!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorit ...
- POJ1088 滑雪题解+HDU 1078(记忆化搜索DP)
Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...
- hdu1078 记忆化搜索
/* hdu 1078 QAQ记忆化搜索 其实还是搜索..因为里面开了一个数组这样可以省时间 (dp[x][y]大于0就不用算了直接返回值) */ #include<stdio.h> #i ...
- HDU 1429 (BFS+记忆化状压搜索)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1429 题目大意:最短时间内出迷宫,可以走回头路,迷宫内有不同的门,对应不同的钥匙. 解题思路: 要是 ...
- HDU 1176 免费馅饼(记忆化搜索)
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
随机推荐
- Mysql有没有语法可以在增加列前进行判断该列是否存在
Mysql没有直接的语法可以在增加列前进行判断该列是否存在,需要写一个存储过程完成同样任务,下面例子是:在sales_order表中增加一列has_sent列 drop procedure if ex ...
- WCF开发框架之插件化应用模式升级
自从在<Winform开发框架之插件化应用框架实现>一文中,介绍并总结了Winform开发框架插件化应用框架的实现后,赢得了很多同行和客户的支持,于是把我的WCF开发框架.混合式开发框架都 ...
- oracle触发器类型
http://www.cnblogs.com/roucheng/p/3506033.html 触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异 ...
- FreeBSD的新一代包管理工具Pkg 1.3.0 发布
Pkg 是 FreeBSD 下一代的打包管理工具,用来替代原来的 pkg_info/pkg_create/pkg_add 工具,可以本地打包,也提供远程打包,主要是为了方便远程二进制包升级. Pkg ...
- [python拾遗]列表
python列表拾遗 1.列表可以修改,使用 ‘+’ 将一个新列表附加在原列表的尾部: >>> a = [1,'a'] >>> b = a + [2,'b'] &g ...
- 研究jdk关于TreeMap 红黑树算法实现
因为TreeMap的实现方式是用红黑树这种数据结构进行存储的,所以呢我主要通过分析红黑树的实现在看待TreeMap,侧重点也在于如何实现红黑树,因为网上已经有非常都的关于红黑树的实现.我也看了些,但是 ...
- Web Service(一) 基础学习
1 基础的Web Service平台是XML+HTTP. 2 Web Service平台的元素包括:SOAP(Simple Object Access Protocol)简单对象访问协议: UDDI( ...
- SharePoint 2013 新功能探索 之 列表等级设置
一.列表等级及赞功能 ,在SharePoint 2010 中,对列表的等级设定,需要一定时间才能看到,现在可以实时同步,评分人数也能显示出来 等级分为两类 赞和星级评定
- CSS基础选择器温故-1
1.基本选择器语法 2.浏览器兼容性:浏览器对基本选择器都是一路绿灯通行,可以放心使用. 3.通配选择器:选择所有元素,也可以选择某个元素下的所有元素 (1)选择所有元素: *{margin: 0;p ...
- 一道灵活的css笔试题
今天在网上看到一css笔试题,乍一看很简单,实则内部暗藏玄机,题目大概是:九宫格,每格长宽50px,边框宽度5px,鼠标经过边框变红,效果如下: 鼠标路过时: 以下是代码(如有不足之处望多加指正) & ...