hdu 5094 Maze 状态压缩dp+广搜

作者: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)时记录最小步数并退出搜索。

代码如下:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstring>
 5 #include  <queue>
 6 #include  <limits.h>
 7 #include  <queue>
 8 #define     MAXP 11
 9 #define     MAXN 51
10 using namespace std;
11 int bin[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096};
12 int dir[4][2]={{-1, 0}, {0, 1}, {1, 0}, {0, -1}};//左,上,右,下
13 int dp[2050][MAXN][MAXN];
14 int key[MAXN][MAXN];
15 int wall[MAXN][MAXN][MAXN][MAXN];
16 int n, m, p;
17 class state
18 {
19     public:
20         int x, y, key, step;
21 };
22 void solve()
23 {
24     memset(dp, -1, sizeof(dp));
25     state b;
26     b.x = 1;
27     b.y = 1;
28     b.key = key[1][1];
29     b.step = 0;
30     queue<state> qu;
31     qu.push(b);
32     int res = INT_MAX;
33     while( qu.size() > 0 )
34     {
35         state cur = qu.front();
36         qu.pop();
37         for( int i = 0 ; i < 4 ; i++ )
38         {
39             if( cur.x==n && cur.y == m )//到达目的地
40             {
41                 res = min(res, cur.step);
42                 continue;
43             }
44             state next;
45             next.x = cur.x + dir[i][0];
46             next.y = cur.y + dir[i][1];
47             next.key = 0;
48             next.step = 0;
49             //出界
50             if( next.x < 1 || next.x > n  ) continue;
51             if( next.y < 1 || next.y > m ) continue;
52             int w = wall[cur.x][cur.y][next.x][next.y];
53             if( w == 0 ) continue;//是墙
54             if( w > 0 && (cur.key/bin[w]%2 == 0)) continue;//是门没钥匙
55             next.step = cur.step+1;
56             next.key = cur.key | key[next.x][next.y];
57             if( dp[next.key][next.x][next.y]< 0 )
58             {
59                 dp[next.key][next.x][next.y]  = next.step;
60                 qu.push(next);
61             }
62             else if(dp[next.key][next.x][next.y] > next.step)
63             {
64                 dp[next.key][next.x][next.y] = next.step;
65                 qu.push(next);
66             }
67         }
68     }
69     if( res == INT_MAX )
70     {
71         printf("-1\n");
72         return;
73     }
74     printf("%d\n", res);
75 }
76 int main(int argc, char *argv[])
77 {
78     while(scanf("%d%d%d", &n, &m, &p)!=EOF)
79     {
80         memset(key, 0, sizeof(key));
81         memset(wall, -1, sizeof(wall));
82         int tmp;
83         scanf("%d", &tmp);
84         int x1, x2, y1, y2, type;
85         for( int i = 0 ; i < tmp ; i++ )
86         {
87             scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &type);
88             wall[x1][y1][x2][y2] = type;
89             wall[x2][y2][x1][y1] = type;
90         }
91         scanf("%d", &tmp);
92         for( int i = 0 ; i < tmp ; i++ )
93         {
94             scanf("%d%d%d", &x1, &x2, &type);
95             key[x1][x2] |= bin[type];
96         }
97         solve();
98     }
99 }
View Code

 

posted @ 2014-11-12 14:18  jostree  阅读(446)  评论(0编辑  收藏  举报