• 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
    ",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
    ",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
    ");
    161         else
    162             printf("%d
    ",minn);
    163     }
    164     return 0;
    165 }
  • 相关阅读:
    前端总结挺全面的
    cmd与bat脚本的使用
    Spring控制反转(IoC)的理解
    C# 中迭代器
    URL 分页并排序
    结合Flash上传文件时显示进度条
    C# 语言特性
    where T:new()
    图片缩放特效
    C# 隐藏窗体 ALT+TAb不可见
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3991885.html
Copyright © 2020-2023  润新知