首页 > 代码库 > HDU 5025 状态压缩蛇+bfs+dp

HDU 5025 状态压缩蛇+bfs+dp

题目大意:
孙悟空要找到一条花费时间最短的路径,路上为S的代表有蛇,经过需多花一分钟,其他情况下都是走过花费一分钟,但数字必须依次得到,最后到了唐僧处,可以经过也可以救出,救出前提是得到所有种类的钥匙

 

这道题,我们不断找到到达每一个点的不同状态下的最小花费时间,用dp[N][N][11][status]来存,status代表所有蛇的状态,因为蛇只有5条,所以status<32,不会爆掉。

类似spfa中不断对某个状态进行弛缓操作,如果成功就更新数据后入队,否则不再入队。

这题之所以不能dfs来做,是因为dfs不断从一个点出发搜索一条连续的值,这里因为可以重复经过,也无法设置visit量,而且对于某一点来说到起点的曼哈顿距离都是一样的,由前一个状态确认下一个状态的最好方法还是bfs,bfs过程需要注意什么时候入队,出队,数据的更新。dfs重复操作太多,也会超时。

 

代码:

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 #include <algorithm>  5 #include <queue>  6 using namespace std;  7   8 #define N 102  9 int pos[N][N]; 10  11 struct Node{ 12     int x,y,key,status; 13 }; 14  15 char mat[N][N]; 16 int dp[N][N][11][1<<5],n,m; 17 int a,b,c,d,s[N][N]; 18 int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; 19 queue<Node> q; 20  21 void ok(Node p1,Node p2,int x) 22 { 23     if(dp[p2.x][p2.y][p2.key][p2.status]>dp[p1.x][p1.y][p1.key][p1.status]+x) 24     { 25         dp[p2.x][p2.y][p2.key][p2.status]=dp[p1.x][p1.y][p1.key][p1.status]+x; 26         //printf("%d %d %d\n",p2.x,p2.y,dp[p2.x][p2.y][p2.key][p2.status]); 27         q.push(p2); 28     } 29 } 30  31 void bfs(int x,int y) 32 { 33     while(!q.empty()) 34         q.pop(); 35  36     Node t; 37     t.x=x,t.y=y,t.key=0,t.status=0; 38     q.push(t); 39     while(!q.empty()){ 40  41         Node p1 = q.front(); 42         q.pop(); 43  44         for(int i=0;i<4;i++){ 45             Node p2; 46             p2.x = p1.x+dir[i][0]; 47             p2.y = p1.y+dir[i][1]; 48             if(p2.x>=0&&p2.x<n&&p2.y>=0&&p2.y<n&&mat[p2.x][p2.y]!=#){ 49                 if(mat[p2.x][p2.y]==.){ 50                     p2.key = p1.key; 51                     p2.status = p1.status; 52                     //kcout<<"in.."<<endl; 53                     if(dp[p2.x][p2.y][p2.key][p2.status]>dp[p1.x][p1.y][p1.key][p1.status]+1) 54                     { 55                         //cout<<"in.."<<endl; 56                         dp[p2.x][p2.y][p2.key][p2.status]=dp[p1.x][p1.y][p1.key][p1.status]+1; 57                         q.push(p2); 58                     } 59                 } 60  61                 else if(mat[p2.x][p2.y]==S){ 62                     int ins = pos[p2.x][p2.y]; 63                     //cout<<"inS"<<endl; 64                     if(p1.status & 1<<(ins-1)){ 65                         p2.key = p1.key; 66                         p2.status = p1.status; 67                         if(dp[p2.x][p2.y][p2.key][p2.status]>dp[p1.x][p1.y][p1.key][p1.status]+1) 68                         { 69                        // cout<<"inS"<<endl; 70                             dp[p2.x][p2.y][p2.key][p2.status]=dp[p1.x][p1.y][p1.key][p1.status]+1; 71                             q.push(p2); 72                         } 73                     } 74                     else{ 75                         p2.key = p1.key; 76                         p2.status = p1.status|1<<(ins-1); 77                         if(dp[p2.x][p2.y][p2.key][p2.status]>dp[p1.x][p1.y][p1.key][p1.status]+2) 78                         { 79                        // cout<<"inS"<<endl; 80                             dp[p2.x][p2.y][p2.key][p2.status]=dp[p1.x][p1.y][p1.key][p1.status]+2; 81                             q.push(p2); 82                         } 83                     } 84  85                 } 86  87                 else if(mat[p2.x][p2.y]==T){ 88                     p2.key = p1.key; 89                     p2.status = p1.status; 90  91                     if(p1.key == m){ 92                         if(dp[p2.x][p2.y][p2.key][p2.status]>dp[p1.x][p1.y][p1.key][p1.status]+1) 93                         { 94                             dp[p2.x][p2.y][p2.key][p2.status]=dp[p1.x][p1.y][p1.key][p1.status]+1; 95                         } 96                     } 97                     else{ 98                         if(dp[p2.x][p2.y][p2.key][p2.status]>dp[p1.x][p1.y][p1.key][p1.status]+1) 99                         {100                             dp[p2.x][p2.y][p2.key][p2.status]=dp[p1.x][p1.y][p1.key][p1.status]+1;101                         }102                         q.push(p2);103                     }104                 }105 106                 else{107                     int tmp = mat[p2.x][p2.y] - 0;108                     if(tmp == p1.key+1) {109                         p2.key = p1.key+1;110                         p2.status = p1.status;111                         ok(p1,p2,1);112                     }113                     else{114                         p2.key = p1.key;115                         p2.status = p1.status;116                         ok(p1,p2,1);117                     }118                 }119             }120         }121     }122 }123 124 int main()125 {126     while(~scanf("%d%d",&n,&m)){127         if(n==0&&m==0)128             break;129 130         int tmp = 0;131         memset(dp,0x3f,sizeof(dp));132 133         for(int i=0;i<n;i++){134             for(int j=0;j<n;j++){135                 cin>>mat[i][j];136                 if(mat[i][j] == K)137                     a=i,b=j;138                 else if(mat[i][j] == T)139                     c=i,d=j;140 141                 else if(mat[i][j] == S)142                     pos[i][j]=++tmp;143             }144         }145         146         //确定孙悟空出发点后可以把当前点想象成和‘.‘一样的功能147         mat[a][b] = .;148         dp[a][b][0][0] = 0;149         bfs(a,b);150 151         int minn = 0x3f3f3f3f;152 153         for(int i = 0;i<32;i++){154             //printf("%d\n",dp[c][d][m][i]);155             if(dp[c][d][m][i]<minn)156                 minn = dp[c][d][m][i];157         }158 159         if(minn == 0x3f3f3f3f)160             printf("impossible\n");161         else162             printf("%d\n",minn);163     }164     return 0;165 }

 

HDU 5025 状态压缩蛇+bfs+dp