作者: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. Android AndroidManifest 清单文件以及权限具体解释

    每一个Android应用都须要一个名为AndroidManifest.xml的程序清单文件,这个清单文件名称是固定的而且放在每一个Android应用的根文件夹下.它定义了该应用对于Android系统来 ...

  2. PHP PDO函数库具体解释

    文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/565 PDO是一个"数据库訪问抽象层",作用是统一各种数据库的訪问接口 ...

  3. 获取windows版本信息

    procedure TForm1.Button1Click(Sender: TObject); Var     OSVI:OSVERSIONINFO; begin     OSVI.dwOSversi ...

  4. android学习日记19--四大组件之BroadcastReciver(广播接收者)

    二.BroadcastReciver(广播接收者) 1.简述 BroadcastReciver位于android.content包下,主要用于对广播消息(Intent)的过滤并响应的控件.可以理解为全 ...

  5. Unity手游之路&lt;七&gt;角色控制器

    我们要控制角色的移动,能够所有细节都由自己来实现.控制角色模型的移动,同一时候移动摄影机,改变视角.当然Unity也提供了一些组件,能够让我们做更少的工作,实现我们所期望的功能.今天我们就一起系统来学 ...

  6. 四、IP地址转换

    IP地址与端口 TCP/IP(传输控制协议/网际协议)不是一个协议,而是一组协议的总称,包括IP.TCP.UDP.ICMP.ARP等.它规范了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据 ...

  7. (转载)c语言指针学习

    前言 近期俄罗斯的陨石.四月的血月.五月北京的飞雪以及天朝各种血腥和混乱,给人一种不详的预感.佛祖说的末法时期,五浊恶世 ,十恶之世,人再无心法约束,道德沦丧,和现在正好吻合.尤其是在天朝,空气,水, ...

  8. javascript笔记03:易犯错的比较运算

    1.比较两个值是否相等的常见运算: " //false == "" //true == " //true false == "false" ...

  9. Android_Intent_data_type

    layout.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" x ...

  10. linux内核结构

    Linux内核子系统: 分别是:进程调度(SCHED).进程间通信(IPC).虚拟文件系统(VFS).内存管理(MM).网络通信(NET) 进程调度与内存管理之间的关系:这两个子系统互相依赖.在多道程 ...