zoukankan      html  css  js  c++  java
  • hdu 5025 Saving Tang Monk 状态压缩dp+广搜

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

    题目链接:hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    使用dp[x][y][key][s]来记录孙悟空的坐标(x,y)、当前获取到的钥匙key和打死的蛇s。由于钥匙具有先后顺序,因此在钥匙维度中只需开辟大小为10的长度来保存当前获取的最大编号的钥匙即可。蛇没有先后顺序,其中s的二进制的第i位等于1表示打死了该蛇,否则表示没打死。然后进行广度优先搜索即可,需要注意的是即使目前没有拿到第k-1把钥匙,也可以经过房间k或唐僧,只不过无法获取钥匙k和救唐僧而已。

    代码如下:

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <iostream>
      4 #include <cstring>
      5 #include  <queue>
      6 #include  <limits.h>
      7 #define     MAXN 101
      8 #define     MAXM 10
      9 using namespace std;
     10 int dir[4][2]={{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
     11 char map[MAXN][MAXN];
     12 int bin[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096};
     13 int dp[MAXN][MAXN][10][35];
     14 int n, m;
     15 class state
     16 {
     17     public:
     18         int x, y, step, key, s;
     19 };
     20 state start, ed;
     21 void solve()
     22 {
     23     memset(dp, -1, sizeof(dp));
     24     queue<state> qu; 
     25     qu.push(start);
     26     int res = INT_MAX;
     27     while( qu.size() > 0 )
     28     {
     29         state cur = qu.front();
     30         qu.pop();
     31         for( int i = 0 ; i < 4 ; i++ )
     32         {
     33             if( cur.x == ed.x && cur.y == ed.y && cur.key== m )
     34             {
     35                 res = min(res, cur.step);
     36                 continue;
     37             }
     38             state next;
     39             next.x = cur.x+dir[i][0];
     40             next.y = cur.y+dir[i][1];
     41             next.key = cur.key;
     42             next.s = cur.s;
     43             next.step = cur.step;
     44             if( next.x < 0 || next.x >= n || next.y < 0 || next.y >= n )//出界
     45             {
     46                 continue;
     47             }
     48             char tmp = map[next.x][next.y];
     49             if( tmp  == '#' )//陷阱
     50             {
     51                 continue;
     52             }
     53             if( tmp >= '1' && tmp <= '9' && cur.key >= tmp-'0'-1 )//有钥匙
     54             {
     55                 next.step = cur.step+1;
     56                 next.key = max(cur.key, tmp - '0');
     57                 next.s = cur.s;
     58             }
     59             else if( tmp >= 'A' && tmp <= 'F')//蛇
     60             {
     61                 if( cur.s/bin[tmp-'A']%2 == 1 )
     62                 {
     63                     next.step = cur.step + 1;    
     64                 }
     65                 else
     66                 {
     67                     next.step = cur.step + 2;
     68                 }
     69                 next.key = cur.key;
     70                 next.s = cur.s | bin[tmp-'A'];
     71             }
     72             else
     73             {
     74                 next.key = cur.key;
     75                 next.step = cur.step+1;
     76                 next.s = cur.s;
     77             }
     78             int dptmp = dp[next.x][next.y][next.key][next.s];
     79             if( dptmp < 0 )
     80             {
     81                 dp[next.x][next.y][next.key][next.s] = next.step;
     82                 qu.push(next);
     83             }
     84             else if(dptmp > next.step)
     85             {
     86                 dp[next.x][next.y][next.key][next.s] = next.step;
     87                 qu.push(next);
     88             }
     89         }
     90     }
     91     if( res == INT_MAX )
     92     {
     93         printf("impossible
    ");
     94         return;
     95     }
     96     printf("%d
    ", res);
     97 }
     98 int main(int argc, char *argv[])
     99 {
    100     char tmp[MAXN+1];
    101     while(1)
    102     {
    103         scanf("%d%d", &n, &m);
    104         if( n == 0 && m == 0 ) return 0;
    105         int sn = 0;
    106         for( int i = 0 ; i < n ; i++ )
    107         {
    108             scanf("%s", tmp); 
    109             for( int j = 0 ; j < n ; j++ )
    110             {
    111                 if( tmp[j] == 'K' )
    112                 {
    113                     start.x = i;
    114                     start.y = j;
    115                     start.key = 0;
    116                     start.step = 0;
    117                     start.s = 0;
    118                 }
    119                 else if( tmp[j] == 'T' )
    120                 {
    121                     ed.x = i;    
    122                     ed.y = j;
    123                 }
    124                 else if( tmp[j] == 'S' )
    125                 {
    126                     map[i][j] = 'A'+sn;
    127                     sn++;
    128                     continue;
    129                 }
    130                 map[i][j] = tmp[j];
    131             }
    132         }
    133         solve();
    134     }
    135 }
    View Code
  • 相关阅读:
    HttpServletRequest和HttpServletResponse实例
    ioc autofac简单示例
    sql left join 字符串
    sqlserver split函数
    类型同时存在于A.dll和B.dll中的解决办法
    ef使用dbfirst方式连接mysql
    html5 图片上传 预览
    webservice使用EF生成的model序列化问题
    sqlserver2008数据库文件降级为sqlserver2005文件
    [转]webapi部署在IIS7.5报404的解决方案
  • 原文地址:https://www.cnblogs.com/jostree/p/4092939.html
Copyright © 2011-2022 走看看