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 ...
随机推荐
- jsp iframe example
1. jsp中用iframe的方式在body中展示列表, 可以通过父元素的宽.高来设定iframe的宽高. <div class="wrapper" style=" ...
- 如何使用mybatis《二》
前边阐述了如何在java项目中使用mybatis,我们使用的是映射文件的方式,在获得具体的数据操作方法时需要传入映射文件中namespace+“.”方法名称,这种方式有时候会感觉很不爽,很麻烦.我们在 ...
- 3kb jQuery代码搞定各种树形选择。
自制Jquery树形选择插件. 对付各种树形选择(省市,分类..)90行Jquery代码搞定,少说废话直接上插件代码.稍后介绍使用说明.是之前写的一个插件的精简版. 1.Jquery插件代码 /* * ...
- 深入理解MySQL开发性能优化.pptx
深入理解MySQL开发性能优化.pptx,依旧上传baidu pan http://pan.baidu.com/s/1jIwGslS,视频暂未出,培训完成后会更新.
- js的alert和confirm美化
--前言-- window对象的alert和confirm标准方法在不同浏览器的显示效果不太相同,有个相同点是都不是很美观.我们的想法是使用js和css分别仿照它们,提供另一套函数,使在不同浏览器的有 ...
- javascript宿主对象之window.screen、window.close()/open()、window.moveTo、window.resizeTo
window.screen属性所提供的是浏览器以外的信息.这里只简单的概述一下: screen.availWidth - 可用的屏幕宽度 (除去操作系统菜单) screen.availHeight - ...
- 上载EXCEL到SAP系统的方法之一
TEXT_CONVERT_XLS_TO_SAP实例 使用:gui_upload去上传excel数据,每次都出现乱码,不管中文英文都乱码. 至今不知道gui_upload是否支持excel文件上传,. ...
- C# 线程同步
Mutex 类 使用Mutex类来同步两个单独的程序.Mutex是一种原始的同步方式,其只对一个线程授予对共享资源的独占访问. const string NutexName = "C&quo ...
- GridControl列自动匹配宽度
//自动调整所有字段宽度this.gridView1.BestFitColumns(); //调整某列字段宽度this.gridView1.Columns[n].BestFit(); 大多是网上零散找 ...
- 聊聊GISer的职业发展
一.前言 去年写了一篇名为<GISer们还有机会屌丝逆袭吗?>的博文,希望能和广大GISer一起探讨地理信息产业留给小团队和个人的机会.文章发布后,很多GISer通过网络和我进行了交流,其 ...