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

 

你可能感兴趣的:(HDU)