作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html

题目链接:hdu 5094 Maze 状态压缩dp+广搜

使用广度优先搜索,dp[key][x][y]表示在拥有钥匙key并在坐标(x,y)时需要的最少的步数,key的二进制的第i位等于1则代表拥有第i把钥匙。

需要注意以下几点:

1.可能存在同一坐标有多把钥匙。

2.墙和门是在两个坐标间进行移动时的障碍,并不在坐标点上,因此两个方向的移动都要加入wall数组。

2.可以使用方向数组来进行上下左右的搜索。

3.搜索到坐标(n,m)时记录最小步数并退出搜索。

代码如下:

 #include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <queue>
#include <limits.h>
#include <queue>
#define MAXP 11
#define MAXN 51
using namespace std;
int bin[] = {, , , , , , , , , , , , };
int dir[][]={{-, }, {, }, {, }, {, -}};//左,上,右,下
int dp[][MAXN][MAXN];
int key[MAXN][MAXN];
int wall[MAXN][MAXN][MAXN][MAXN];
int n, m, p;
class state
{
public:
int x, y, key, step;
};
void solve()
{
memset(dp, -, sizeof(dp));
state b;
b.x = ;
b.y = ;
b.key = key[][];
b.step = ;
queue<state> qu;
qu.push(b);
int res = INT_MAX;
while( qu.size() > )
{
state cur = qu.front();
qu.pop();
for( int i = ; i < ; i++ )
{
if( cur.x==n && cur.y == m )//到达目的地
{
res = min(res, cur.step);
continue;
}
state next;
next.x = cur.x + dir[i][];
next.y = cur.y + dir[i][];
next.key = ;
next.step = ;
//出界
if( next.x < || next.x > n ) continue;
if( next.y < || next.y > m ) continue;
int w = wall[cur.x][cur.y][next.x][next.y];
if( w == ) continue;//是墙
if( w > && (cur.key/bin[w]% == )) continue;//是门没钥匙
next.step = cur.step+;
next.key = cur.key | key[next.x][next.y];
if( dp[next.key][next.x][next.y]< )
{
dp[next.key][next.x][next.y] = next.step;
qu.push(next);
}
else if(dp[next.key][next.x][next.y] > next.step)
{
dp[next.key][next.x][next.y] = next.step;
qu.push(next);
}
}
}
if( res == INT_MAX )
{
printf("-1\n");
return;
}
printf("%d\n", res);
}
int main(int argc, char *argv[])
{
while(scanf("%d%d%d", &n, &m, &p)!=EOF)
{
memset(key, , sizeof(key));
memset(wall, -, sizeof(wall));
int tmp;
scanf("%d", &tmp);
int x1, x2, y1, y2, type;
for( int i = ; i < tmp ; i++ )
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &type);
wall[x1][y1][x2][y2] = type;
wall[x2][y2][x1][y1] = type;
}
scanf("%d", &tmp);
for( int i = ; i < tmp ; i++ )
{
scanf("%d%d%d", &x1, &x2, &type);
key[x1][x2] |= bin[type];
}
solve();
}
}

hdu 5094 Maze 状态压缩dp+广搜的更多相关文章

  1. hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...

  2. HDU 3001(状态压缩dp)

    状态压缩dp的第一题! 题意:Mr ACMer想要进行一次旅行,他决定访问n座城市.Mr ACMer 可以从任意城市出发,必须访问所有的城市至少一次,并且任何一个城市访问的次数不能超过2次.n座城市间 ...

  3. hdu 4856 Tunnels 状态压缩dp

    Tunnels Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem ...

  4. HDU 3001【状态压缩DP】

    题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数 ...

  5. hdu 5045 Contest(状态压缩DP)

    题解:我们使用一个二位数组dp[i][j]记录进行到第i个任务时,人组合为j时的最大和(这里的j我们用二进制的每位相应一个人). 详细见代码: #include <iostream> #i ...

  6. hdu 3091 Necklace 状态压缩dp *******

    Necklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)Total ...

  7. hdu 4628 Pieces 状态压缩dp

    Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  8. HDU 2167 Pebbles 状态压缩dp

    Pebbles Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  9. HDU 1074 (状态压缩DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...

随机推荐

  1. cocos2d-x 判断点击命中坐标的几种方法

    转自:http://www.cnblogs.com/jiackyan/archive/2013/04/14/3019893.html //重载 virtual bool ccTouchBegan(CC ...

  2. NSMutableAttributedString iOS 在UILabel显示不同的字体和颜色(转)

    在项目开发中,我们经常会遇到在这样一种情形:在一个UILabel 使用不同的颜色或不同的字体来体现字符串,在iOS 以后我们可以很轻松的实现这一点,官方的API 为我们提供了UILabel类的attr ...

  3. hdu4759 Poker Shuffle 2013 ACM/ICPC Asia Regional Changchun Online

    找了很久的规律,只看十进制数字,各种乱七八糟的规律=没规律!看了别人的解题报告,虽然看懂了,可是怎么发现的这个规律呢T.T~想了很久很久~ 以下是转载的别人的图,自己再画太麻烦了~全部看出0~2n-1 ...

  4. 关于 ioctl 的 FIONREAD 參数

    ioctl 是用来设置硬件控制寄存器,或者读取硬件状态寄存器的数值之类的.而read,write 是把数据丢入缓冲区,硬件的驱动从缓冲区读取数据一个个发送或者把接收的数据送入缓冲区. ioctl(ke ...

  5. android131 360 04 手机安全页面

    ## Root权限 ## > 什么是Root权限? Root权限相当于系统管理员权限, 有了root权限,就可以随意修改和删除手机内部的文件. > 一般手机购买之后, 都没有root权限. ...

  6. LLBLGen代码生成工具

    LLBLGen代码生成工具 下载地址:http://www.llblgen.com/ 最新版本4.2 概述 LLBLGen是一个数据访问的解决方案; 你使用LLBLGen创建实体/域模型,定义了映射和 ...

  7. Java自学成长路线(转载)

    JAVA自学之路 一:学会选择  决心做软件的,大多数人选的是java,或是.net,也有一些选择了手机.嵌入式.游戏.3G.测试等.  JAVA是一种平台,也是一种程序设计语言,如何学好程序设计不仅 ...

  8. VM11安装Mac OS X 10.10

    工具/原料 1. VMware Workstation 11.12 2. unlocker 206(for OS X 插件补丁) 3. Mac OS X 10.10镜像 方法/步骤   有图有真相,哈 ...

  9. phpcms v9 模板标签说明整理

    1.{template "content","header"} 2.网站网址调用:{siteurl($siteid)}: 3.标签get:分页,{pc:get ...

  10. jvm内存模型及分配参数

    jvm内存模型 程序计数器:是一块很小的内存空间.当线程数量超过cpu数量时,线程之间根据时间片轮询抢夺cpu资源.每一个线程都必须用一个独立的程序计数器,用于记录下一条要运行的指令. java虚拟机 ...